enso/app/gui2/shared/util/data/opt.ts
Kaz Wesley 343a644051
Syntactic synchronization, automatic parentheses, metadata in Ast (#8893)
- Synchronize Y.Js clients by AST (implements #8237).
- Before committing an edit, insert any parentheses-nodes needed for the concrete syntax to reflect tree structure (fixes #8884).
- Move `externalId` and all node metadata into a Y.Map owned by each `Ast`. This allows including metadata changes in an edit, enables Y.Js merging of changes to different metadata fields, and will enable the use of Y.Js objects in metadata. (Implements #8804.)

### Important Notes

- Metadata is now set and retrieved through accessors on the `Ast` objects.
- Since some metadata edits need to take effect in real time (e.g. node dragging), new lower-overhead APIs (`commitDirect`, `skipTreeRepair`) are provided for careful use in certain cases.
- The client is now bundled as ESM.
- The build script cleans up git-untracked generated files in an outdated location, which fixes lint errors related to `src/generated` that may occur when switching branches.
2024-02-02 10:22:18 +01:00

26 lines
1.2 KiB
TypeScript

/** @file A value that may be `null` or `undefined`. */
/** Optional value type. This is a replacement for `T | null | undefined` that is more
* convenient to use. We do not select a single value to represent "no value", because we are using
* libraries that disagree whether `null` (e.g. Yjs) or `undefined` (e.g. Vue) should be used for
* that purpose. We want to be compatible with both without needless conversions. In our own code,
* we should return `undefined` for "no value", since that is the default value for empty or no
* `return` expression. In order to test whether an `Opt<T>` is defined or not, use `x == null` or
* `isSome` function.
*
* Note: For JSON-serialized data, prefer explicit `null` over `undefined`, since `undefined` is
* not serializable. Alternatively, use optional field syntax (e.g. `{ x?: number }`). */
export type Opt<T> = T | null | undefined
export function isSome<T>(value: Opt<T>): value is T {
return value != null
}
export function isNone(value: Opt<any>): value is null | undefined {
return value == null
}
export function mapOr<T, R>(optional: Opt<T>, fallback: R, mapper: (value: T) => R): R {
return isSome(optional) ? mapper(optional) : fallback
}