@expressive/mvc 0.87.0 → 0.89.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -19
- package/dist/component.d.ts +28 -16
- package/dist/component.js +53 -72
- package/dist/component.js.map +1 -1
- package/dist/context.d.ts +28 -26
- package/dist/context.js +45 -27
- package/dist/context.js.map +1 -1
- package/dist/dispatch.d.ts +6 -1
- package/dist/dispatch.js +14 -6
- package/dist/dispatch.js.map +1 -1
- package/dist/field/def.d.ts +3 -3
- package/dist/field/def.js +7 -7
- package/dist/field/def.js.map +1 -1
- package/dist/field/get.d.ts +16 -16
- package/dist/field/get.js +21 -5
- package/dist/field/get.js.map +1 -1
- package/dist/field/has.d.ts +8 -8
- package/dist/field/has.js +3 -3
- package/dist/field/has.js.map +1 -1
- package/dist/field/map.d.ts +2 -2
- package/dist/field/map.js +2 -2
- package/dist/field/map.js.map +1 -1
- package/dist/field/ref.d.ts +8 -8
- package/dist/field/ref.js +3 -3
- package/dist/field/ref.js.map +1 -1
- package/dist/field/set.js +1 -1
- package/dist/field/set.js.map +1 -1
- package/dist/hot.d.ts +5 -8
- package/dist/hot.js +126 -18
- package/dist/hot.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/jsx-dev-runtime.d.ts +1 -2
- package/dist/jsx-dev-runtime.js +1 -1
- package/dist/jsx-runtime.d.ts +77 -4
- package/dist/jsx-runtime.js +67 -2
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/observable.d.ts +7 -4
- package/dist/observable.js +94 -27
- package/dist/observable.js.map +1 -1
- package/dist/state.d.ts +154 -112
- package/dist/state.js +115 -192
- package/dist/state.js.map +1 -1
- package/package.json +7 -5
- package/dist/_virtual/_rolldown/runtime.js +0 -18
- package/dist/caught.d.ts +0 -5237
- package/dist/caught.js +0 -64
- package/dist/caught.js.map +0 -1
- package/dist/runtime.d.ts +0 -72
- package/dist/runtime.js +0 -70
- package/dist/runtime.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Context } from "./context.js";
|
|
2
|
-
import {
|
|
3
|
-
import { Caught } from "./caught.js";
|
|
2
|
+
import { Model, unbind } from "./state.js";
|
|
4
3
|
import { Component } from "./component.js";
|
|
5
4
|
import { pending } from "./dispatch.js";
|
|
6
5
|
import { def } from "./field/def.js";
|
|
@@ -9,4 +8,4 @@ import { has } from "./field/has.js";
|
|
|
9
8
|
import { map } from "./field/map.js";
|
|
10
9
|
import { ref } from "./field/ref.js";
|
|
11
10
|
import { set } from "./field/set.js";
|
|
12
|
-
export {
|
|
11
|
+
export { Component, Context, Model, Model as State, def, Model as default, get, has, map, pending, ref, set, unbind };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Caught } from "./caught.js";
|
|
2
|
-
import { State, unbind } from "./state.js";
|
|
3
1
|
import { pending } from "./dispatch.js";
|
|
2
|
+
import { Model, unbind } from "./state.js";
|
|
4
3
|
import { Context } from "./context.js";
|
|
5
4
|
import { def } from "./field/def.js";
|
|
6
5
|
import { set } from "./field/set.js";
|
|
@@ -11,9 +10,9 @@ import { map } from "./field/map.js";
|
|
|
11
10
|
import { ref } from "./field/ref.js";
|
|
12
11
|
|
|
13
12
|
//#region src/index.ts
|
|
14
|
-
/** @deprecated Import `{
|
|
15
|
-
var src_default =
|
|
13
|
+
/** @deprecated Import `{ Model }` as a named export. Adapter-augmented `Model.*` types are not visible through the default alias. */
|
|
14
|
+
var src_default = Model;
|
|
16
15
|
|
|
17
16
|
//#endregion
|
|
18
|
-
export {
|
|
17
|
+
export { Component, Context, Model, Model as State, def, src_default as default, get, has, map, pending, ref, set, unbind };
|
|
19
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export { def } from './field/def';\nexport { get } from './field/get';\nexport { has } from './field/has';\nexport { map } from './field/map';\nexport { set } from './field/set';\nexport { ref } from './field/ref';\n\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export { def } from './field/def';\nexport { get } from './field/get';\nexport { has } from './field/has';\nexport { map } from './field/map';\nexport { set } from './field/set';\nexport { ref } from './field/ref';\n\nimport { Model } from './state';\n\nexport { Model, unbind } from './state';\n\n/** @deprecated Renamed to `Model`. */\nexport { Model as State } from './state';\n\n/** @deprecated Import `{ Model }` as a named export. Adapter-augmented `Model.*` types are not visible through the default alias. */\nexport default Model;\nexport { Context } from './context';\nexport { Component } from './component';\nexport { pending } from './dispatch';\n"],"mappings":";;;;;;;;;;;;;AAeA,kBAAe"}
|
package/dist/jsx-dev-runtime.js
CHANGED
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1,12 +1,85 @@
|
|
|
1
|
-
import { Fragment, Host, jsx, jsxs } from "./runtime.js";
|
|
2
1
|
import { Component } from "./component.js";
|
|
3
2
|
|
|
4
3
|
//#region src/jsx-runtime.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Per-adapter interpretation manifest. Each adapter augments this interface to
|
|
6
|
+
* declare how it renders; the first member is `node` - the element type produced
|
|
7
|
+
* by `Component.render` (surfaced as `Component.Node`) - alongside `intrinsics`,
|
|
8
|
+
* the host's tag map (surfaced as `JSX.IntrinsicElements`), `elementClass`,
|
|
9
|
+
* the instance a class must construct to render as an element, and optionally
|
|
10
|
+
* `element`, further element types the host renders (joined into
|
|
11
|
+
* `JSX.ElementType`).
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* declare module '@expressive/mvc/jsx-runtime' {
|
|
15
|
+
* interface Host {
|
|
16
|
+
* node: React.ReactNode;
|
|
17
|
+
* intrinsics: React.JSX.IntrinsicElements;
|
|
18
|
+
* elementClass: React.Component<any, any>;
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Only one adapter is expected per compilation; two augmenting the same member
|
|
24
|
+
* with different types in the same build would conflict - by design.
|
|
25
|
+
*/
|
|
26
|
+
interface Host {}
|
|
27
|
+
/**
|
|
28
|
+
* Host runtime, registered by an adapter (e.g. `@expressive/react`) as an
|
|
29
|
+
* import side effect. One host per build - a second registration with a
|
|
30
|
+
* different runtime throws.
|
|
31
|
+
*
|
|
32
|
+
* Members are ambient host capabilities: plain functions the host uniquely
|
|
33
|
+
* owns, callable outside render - element mechanics always, plus optional
|
|
34
|
+
* extras that fall back sanely when absent. Hook-shaped (render-resident)
|
|
35
|
+
* capabilities do not belong here; those live with the adapter.
|
|
36
|
+
*/
|
|
37
|
+
interface HostRuntime {
|
|
38
|
+
childrenOf(children: unknown): Component.Node[];
|
|
39
|
+
isElement(node: unknown): boolean;
|
|
40
|
+
jsx(type: unknown, props: object, key?: unknown): Component.Node;
|
|
41
|
+
jsxDEV?(type: unknown, props: object, key?: unknown, isStatic?: boolean, source?: object, self?: unknown): Component.Node;
|
|
42
|
+
jsxs(type: unknown, props: object, key?: unknown): Component.Node;
|
|
43
|
+
propsOf(node: unknown): Record<string, unknown>;
|
|
44
|
+
typeOf(node: unknown): unknown;
|
|
45
|
+
Fragment: unknown;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Agnostic Fragment sentinel. The runtime entries translate it to the host's
|
|
49
|
+
* Fragment on element creation; `typeOf` translates back, so identity checks
|
|
50
|
+
* against this value hold for fragments from either pragma.
|
|
51
|
+
*/
|
|
52
|
+
declare const Fragment: unique symbol;
|
|
53
|
+
/**
|
|
54
|
+
* Register the host runtime. Idempotent for the same runtime - re-registering
|
|
55
|
+
* picks up members added since (e.g. an optional dev seam). Element mechanics
|
|
56
|
+
* the host leaves unset keep defaults that throw a setup-pointing error;
|
|
57
|
+
* `jsxDEV` is routed around at the call site instead.
|
|
58
|
+
*/
|
|
59
|
+
declare function host(runtime: HostRuntime): void;
|
|
60
|
+
declare function jsx(type: unknown, props: object, key?: unknown): Component.Node;
|
|
61
|
+
declare function jsxs(type: unknown, props: object, key?: unknown): Component.Node;
|
|
62
|
+
/** Dev-transpiled element creation. Hosts without a `jsxDEV` of their own fall
|
|
63
|
+
* back to the production entries (prod-only host under a dev build). */
|
|
64
|
+
declare function jsxDEV(type: unknown, props: object, key?: unknown, isStatic?: boolean, source?: object, self?: unknown): Component.Node;
|
|
65
|
+
/** Flatten `children` to an array of nodes, per the host's semantics. */
|
|
66
|
+
declare function childrenOf(children: unknown): Component.Node[];
|
|
67
|
+
/** Is `node` a host element? */
|
|
68
|
+
declare function isElement(node: unknown): boolean;
|
|
69
|
+
/** Element type of `node`; host Fragments surface as the agnostic `Fragment`. */
|
|
70
|
+
declare function typeOf(node: unknown): unknown;
|
|
71
|
+
/** Props carried by element `node`. */
|
|
72
|
+
declare function propsOf(node: unknown): Record<string, unknown>;
|
|
5
73
|
declare namespace JSX {
|
|
6
74
|
type Element = Component.Node;
|
|
7
|
-
type ElementType = keyof IntrinsicElements | ((props: any) => Component.Node) | (
|
|
75
|
+
type ElementType = keyof IntrinsicElements | ((props: any) => Component.Node) | (new (...args: any[]) => Host extends {
|
|
76
|
+
elementClass: infer I;
|
|
77
|
+
} ? I : ElementClass) | (Host extends {
|
|
78
|
+
element: infer T;
|
|
79
|
+
} ? T : never);
|
|
8
80
|
/**
|
|
9
|
-
*
|
|
81
|
+
* Class instance contract when no host declares `elementClass`. Gates on the
|
|
82
|
+
* `render` contract alone - requiring full
|
|
10
83
|
* `Component` assignability trips contravariance on `props` members (e.g.
|
|
11
84
|
* the `is` callback narrows per subclass), rejecting every subclass.
|
|
12
85
|
*/
|
|
@@ -32,5 +105,5 @@ declare namespace JSX {
|
|
|
32
105
|
} ? T : {};
|
|
33
106
|
}
|
|
34
107
|
//#endregion
|
|
35
|
-
export { Fragment, JSX, jsx, jsxs };
|
|
108
|
+
export { Fragment, Host, HostRuntime, JSX, childrenOf, host, isElement, jsx, jsxDEV, jsxs, propsOf, typeOf };
|
|
36
109
|
//# sourceMappingURL=jsx-runtime.d.ts.map
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -1,3 +1,68 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/jsx-runtime.ts
|
|
2
|
+
/**
|
|
3
|
+
* Agnostic Fragment sentinel. The runtime entries translate it to the host's
|
|
4
|
+
* Fragment on element creation; `typeOf` translates back, so identity checks
|
|
5
|
+
* against this value hold for fragments from either pragma.
|
|
6
|
+
*/
|
|
7
|
+
const Fragment = Symbol.for("@expressive/mvc.Fragment");
|
|
8
|
+
/** Default for seams only a registered host can provide. */
|
|
9
|
+
function absent() {
|
|
10
|
+
throw new Error("No JSX host is registered for @expressive/mvc. Import a host adapter (e.g. '@expressive/react') before anything renders - typically as the first import of your application entry module.");
|
|
11
|
+
}
|
|
12
|
+
const HOST = {
|
|
13
|
+
childrenOf: absent,
|
|
14
|
+
isElement: absent,
|
|
15
|
+
jsx: absent,
|
|
16
|
+
jsxs: absent,
|
|
17
|
+
propsOf: absent,
|
|
18
|
+
typeOf: absent,
|
|
19
|
+
Fragment
|
|
20
|
+
};
|
|
21
|
+
let registered;
|
|
22
|
+
/**
|
|
23
|
+
* Register the host runtime. Idempotent for the same runtime - re-registering
|
|
24
|
+
* picks up members added since (e.g. an optional dev seam). Element mechanics
|
|
25
|
+
* the host leaves unset keep defaults that throw a setup-pointing error;
|
|
26
|
+
* `jsxDEV` is routed around at the call site instead.
|
|
27
|
+
*/
|
|
28
|
+
function host(runtime) {
|
|
29
|
+
if (registered && registered !== runtime) throw new Error("A different JSX host is already registered for @expressive/mvc. Only one host adapter may be active per build.");
|
|
30
|
+
registered = runtime;
|
|
31
|
+
Object.assign(HOST, runtime);
|
|
32
|
+
}
|
|
33
|
+
/** Translate the agnostic Fragment sentinel to the host's Fragment. */
|
|
34
|
+
function hostType(type) {
|
|
35
|
+
return type === Fragment ? HOST.Fragment : type;
|
|
36
|
+
}
|
|
37
|
+
function jsx(type, props, key) {
|
|
38
|
+
return HOST.jsx(hostType(type), props, key);
|
|
39
|
+
}
|
|
40
|
+
function jsxs(type, props, key) {
|
|
41
|
+
return HOST.jsxs(hostType(type), props, key);
|
|
42
|
+
}
|
|
43
|
+
/** Dev-transpiled element creation. Hosts without a `jsxDEV` of their own fall
|
|
44
|
+
* back to the production entries (prod-only host under a dev build). */
|
|
45
|
+
function jsxDEV(type, props, key, isStatic, source, self) {
|
|
46
|
+
return HOST.jsxDEV ? HOST.jsxDEV(hostType(type), props, key, isStatic, source, self) : isStatic ? jsxs(type, props, key) : jsx(type, props, key);
|
|
47
|
+
}
|
|
48
|
+
/** Flatten `children` to an array of nodes, per the host's semantics. */
|
|
49
|
+
function childrenOf(children) {
|
|
50
|
+
return HOST.childrenOf(children);
|
|
51
|
+
}
|
|
52
|
+
/** Is `node` a host element? */
|
|
53
|
+
function isElement(node) {
|
|
54
|
+
return HOST.isElement(node);
|
|
55
|
+
}
|
|
56
|
+
/** Element type of `node`; host Fragments surface as the agnostic `Fragment`. */
|
|
57
|
+
function typeOf(node) {
|
|
58
|
+
const type = HOST.typeOf(node);
|
|
59
|
+
return type === HOST.Fragment ? Fragment : type;
|
|
60
|
+
}
|
|
61
|
+
/** Props carried by element `node`. */
|
|
62
|
+
function propsOf(node) {
|
|
63
|
+
return HOST.propsOf(node);
|
|
64
|
+
}
|
|
2
65
|
|
|
3
|
-
|
|
66
|
+
//#endregion
|
|
67
|
+
export { Fragment, childrenOf, host, isElement, jsx, jsxDEV, jsxs, propsOf, typeOf };
|
|
68
|
+
//# sourceMappingURL=jsx-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-runtime.js","names":[],"sources":["../src/jsx-runtime.ts"],"sourcesContent":["import type { Component } from './component';\n\n/**\n * Per-adapter interpretation manifest. Each adapter augments this interface to\n * declare how it renders; the first member is `node` - the element type produced\n * by `Component.render` (surfaced as `Component.Node`) - alongside `intrinsics`,\n * the host's tag map (surfaced as `JSX.IntrinsicElements`), `elementClass`,\n * the instance a class must construct to render as an element, and optionally\n * `element`, further element types the host renders (joined into\n * `JSX.ElementType`).\n *\n * ```ts\n * declare module '@expressive/mvc/jsx-runtime' {\n * interface Host {\n * node: React.ReactNode;\n * intrinsics: React.JSX.IntrinsicElements;\n * elementClass: React.Component<any, any>;\n * }\n * }\n * ```\n *\n * Only one adapter is expected per compilation; two augmenting the same member\n * with different types in the same build would conflict - by design.\n */\nexport interface Host { }\n\n/**\n * Host runtime, registered by an adapter (e.g. `@expressive/react`) as an\n * import side effect. One host per build - a second registration with a\n * different runtime throws.\n *\n * Members are ambient host capabilities: plain functions the host uniquely\n * owns, callable outside render - element mechanics always, plus optional\n * extras that fall back sanely when absent. Hook-shaped (render-resident)\n * capabilities do not belong here; those live with the adapter.\n */\nexport interface HostRuntime {\n childrenOf(children: unknown): Component.Node[];\n isElement(node: unknown): boolean;\n jsx(type: unknown, props: object, key?: unknown): Component.Node;\n jsxDEV?(type: unknown, props: object, key?: unknown, isStatic?: boolean, source?: object, self?: unknown): Component.Node;\n jsxs(type: unknown, props: object, key?: unknown): Component.Node;\n propsOf(node: unknown): Record<string, unknown>;\n typeOf(node: unknown): unknown;\n Fragment: unknown;\n}\n\n/**\n * Agnostic Fragment sentinel. The runtime entries translate it to the host's\n * Fragment on element creation; `typeOf` translates back, so identity checks\n * against this value hold for fragments from either pragma.\n */\nexport const Fragment = Symbol.for('@expressive/mvc.Fragment');\n\n/** Default for seams only a registered host can provide. */\nfunction absent(): never {\n throw new Error(\n 'No JSX host is registered for @expressive/mvc. ' +\n \"Import a host adapter (e.g. '@expressive/react') before anything renders - \" +\n 'typically as the first import of your application entry module.'\n );\n}\n\nconst HOST: HostRuntime = {\n childrenOf: absent,\n isElement: absent,\n jsx: absent,\n jsxs: absent,\n propsOf: absent,\n typeOf: absent,\n Fragment\n};\n\nlet registered: HostRuntime | undefined;\n\n/**\n * Register the host runtime. Idempotent for the same runtime - re-registering\n * picks up members added since (e.g. an optional dev seam). Element mechanics\n * the host leaves unset keep defaults that throw a setup-pointing error;\n * `jsxDEV` is routed around at the call site instead.\n */\nexport function host(runtime: HostRuntime) {\n if (registered && registered !== runtime)\n throw new Error(\n 'A different JSX host is already registered for @expressive/mvc. ' +\n 'Only one host adapter may be active per build.'\n );\n\n registered = runtime;\n Object.assign(HOST, runtime);\n}\n\n/** Translate the agnostic Fragment sentinel to the host's Fragment. */\nfunction hostType(type: unknown): unknown {\n return type === Fragment ? HOST.Fragment : type;\n}\n\nexport function jsx(type: unknown, props: object, key?: unknown): Component.Node {\n return HOST.jsx(hostType(type), props, key);\n}\n\nexport function jsxs(type: unknown, props: object, key?: unknown): Component.Node {\n return HOST.jsxs(hostType(type), props, key);\n}\n\n/** Dev-transpiled element creation. Hosts without a `jsxDEV` of their own fall\n * back to the production entries (prod-only host under a dev build). */\nexport function jsxDEV(\n type: unknown,\n props: object,\n key?: unknown,\n isStatic?: boolean,\n source?: object,\n self?: unknown\n): Component.Node {\n return HOST.jsxDEV\n ? HOST.jsxDEV(hostType(type), props, key, isStatic, source, self)\n : isStatic\n ? jsxs(type, props, key)\n : jsx(type, props, key);\n}\n\n/** Flatten `children` to an array of nodes, per the host's semantics. */\nexport function childrenOf(children: unknown): Component.Node[] {\n return HOST.childrenOf(children);\n}\n\n/** Is `node` a host element? */\nexport function isElement(node: unknown): boolean {\n return HOST.isElement(node);\n}\n\n/** Element type of `node`; host Fragments surface as the agnostic `Fragment`. */\nexport function typeOf(node: unknown): unknown {\n const type = HOST.typeOf(node);\n return type === HOST.Fragment ? Fragment : type;\n}\n\n/** Props carried by element `node`. */\nexport function propsOf(node: unknown): Record<string, unknown> {\n return HOST.propsOf(node);\n}\n\n\nexport declare namespace JSX {\n type Element = Component.Node;\n type ElementType =\n | keyof IntrinsicElements\n | ((props: any) => Component.Node)\n | (new (...args: any[]) => Host extends { elementClass: infer I } ? I : ElementClass)\n | (Host extends { element: infer T } ? T : never);\n /**\n * Class instance contract when no host declares `elementClass`. Gates on the\n * `render` contract alone - requiring full\n * `Component` assignability trips contravariance on `props` members (e.g.\n * the `is` callback narrows per subclass), rejecting every subclass.\n */\n interface ElementClass { render(props?: any): Component.Node }\n interface ElementAttributesProperty { props: {} }\n interface ElementChildrenAttribute { children: {} }\n interface IntrinsicAttributes { key?: string | number | null }\n /**\n * Host tag manifest, via the {@link Host} seam. Resolves to `{}` until an\n * adapter augments `Host` with `intrinsics` - agnostic code is\n * components-only by design, since it cannot know what tags a host renders.\n */\n type IntrinsicElements =\n Host extends { intrinsics: infer T extends object } ? T : {};\n}\n"],"mappings":";;;;;;AAoDA,MAAa,WAAW,OAAO,IAAI,2BAA2B;;AAG9D,SAAS,SAAgB;AACvB,OAAM,IAAI,MACR,4LAGD;;AAGH,MAAM,OAAoB;CACxB,YAAY;CACZ,WAAW;CACX,KAAK;CACL,MAAM;CACN,SAAS;CACT,QAAQ;CACR;CACD;AAED,IAAI;;;;;;;AAQJ,SAAgB,KAAK,SAAsB;AACzC,KAAI,cAAc,eAAe,QAC/B,OAAM,IAAI,MACR,iHAED;AAEH,cAAa;AACb,QAAO,OAAO,MAAM,QAAQ;;;AAI9B,SAAS,SAAS,MAAwB;AACxC,QAAO,SAAS,WAAW,KAAK,WAAW;;AAG7C,SAAgB,IAAI,MAAe,OAAe,KAA+B;AAC/E,QAAO,KAAK,IAAI,SAAS,KAAK,EAAE,OAAO,IAAI;;AAG7C,SAAgB,KAAK,MAAe,OAAe,KAA+B;AAChF,QAAO,KAAK,KAAK,SAAS,KAAK,EAAE,OAAO,IAAI;;;;AAK9C,SAAgB,OACd,MACA,OACA,KACA,UACA,QACA,MACgB;AAChB,QAAO,KAAK,SACR,KAAK,OAAO,SAAS,KAAK,EAAE,OAAO,KAAK,UAAU,QAAQ,KAAK,GAC/D,WACE,KAAK,MAAM,OAAO,IAAI,GACtB,IAAI,MAAM,OAAO,IAAI;;;AAI7B,SAAgB,WAAW,UAAqC;AAC9D,QAAO,KAAK,WAAW,SAAS;;;AAIlC,SAAgB,UAAU,MAAwB;AAChD,QAAO,KAAK,UAAU,KAAK;;;AAI7B,SAAgB,OAAO,MAAwB;CAC7C,MAAM,OAAO,KAAK,OAAO,KAAK;AAC9B,QAAO,SAAS,KAAK,WAAW,WAAW;;;AAI7C,SAAgB,QAAQ,MAAwC;AAC9D,QAAO,KAAK,QAAQ,KAAK"}
|
package/dist/observable.d.ts
CHANGED
|
@@ -11,7 +11,10 @@ declare namespace Observer {
|
|
|
11
11
|
*/
|
|
12
12
|
type Notify = (key: Signal) => (() => void) | null | void;
|
|
13
13
|
type EffectCleanup = (update: boolean | null) => void;
|
|
14
|
-
type
|
|
14
|
+
type EffectOutput = EffectCleanup | null | void;
|
|
15
|
+
type Effect<T extends object, R = EffectOutput | Promise<void>> = (this: T, proxy: T, changed: readonly Event[]) => R;
|
|
16
|
+
/** Stops the effect when called; awaited, cancels it and yields its value. */
|
|
17
|
+
type Release<R> = (() => void) & PromiseLike<R>;
|
|
15
18
|
type Event = number | string | symbol;
|
|
16
19
|
type Signal = Event | true | false | null;
|
|
17
20
|
type Callback = () => void | null;
|
|
@@ -46,12 +49,12 @@ declare function event(state: object, key?: Observer.Event | null, silent?: bool
|
|
|
46
49
|
* Create a side-effect which will update whenever values accessed change.
|
|
47
50
|
* Callback is called immediately and whenever values are stale.
|
|
48
51
|
*
|
|
49
|
-
* @param target - Instance of
|
|
52
|
+
* @param target - Instance of Model to observe.
|
|
50
53
|
* @param callback - Function to invoke when values change.
|
|
51
54
|
* @param requireValues - If `true` will throw if accessing a value which is `undefined`.
|
|
52
55
|
*/
|
|
53
|
-
declare function watch<T extends object>(target: T, callback: Observer.Effect<Required<T>>, requireValues: true, transition?: (work: () => void) => void):
|
|
54
|
-
declare function watch<T extends object>(target: T, callback: Observer.Effect<T
|
|
56
|
+
declare function watch<T extends object, R = void>(target: T, callback: Observer.Effect<Required<T>, Observer.EffectOutput | Promise<R>>, requireValues: true, transition?: (work: () => void) => void): Observer.Release<R>;
|
|
57
|
+
declare function watch<T extends object, R = void>(target: T, callback: Observer.Effect<T, Observer.EffectOutput | Promise<R>>, recursive?: boolean, transition?: (work: () => void) => void): Observer.Release<R>;
|
|
55
58
|
declare function capture(scope: (release: (update?: boolean | null) => void) => void): void;
|
|
56
59
|
//#endregion
|
|
57
60
|
export { Observer, capture, event, listener, observer, queued, touch, watch };
|
package/dist/observable.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { enqueue, hold } from "./dispatch.js";
|
|
1
|
+
import { REPORT, enqueue, hold } from "./dispatch.js";
|
|
2
2
|
|
|
3
3
|
//#region src/observable.ts
|
|
4
4
|
const Observer = Symbol("Observer");
|
|
@@ -119,18 +119,61 @@ function watch(target, callback, argument, transition) {
|
|
|
119
119
|
let previous;
|
|
120
120
|
let latest;
|
|
121
121
|
let queued = false;
|
|
122
|
+
let pending = false;
|
|
122
123
|
let suspense;
|
|
123
|
-
|
|
124
|
+
let outcome;
|
|
125
|
+
let awaiting;
|
|
126
|
+
let settle;
|
|
127
|
+
function conclude(ok, value) {
|
|
128
|
+
outcome = {
|
|
129
|
+
ok,
|
|
130
|
+
value
|
|
131
|
+
};
|
|
132
|
+
if (!ok || !queued) finish();
|
|
133
|
+
}
|
|
134
|
+
function finish() {
|
|
135
|
+
const done = awaiting && settle;
|
|
136
|
+
if (!done) return;
|
|
137
|
+
settle = void 0;
|
|
138
|
+
done();
|
|
139
|
+
cleanup();
|
|
140
|
+
}
|
|
141
|
+
function fail(reason) {
|
|
142
|
+
if (!outcome) outcome = {
|
|
143
|
+
ok: false,
|
|
144
|
+
value: /* @__PURE__ */ new Error(`${target} ${reason}`)
|
|
145
|
+
};
|
|
146
|
+
finish();
|
|
147
|
+
}
|
|
148
|
+
function stop(key) {
|
|
149
|
+
if (unset) unset(key);
|
|
150
|
+
unset = void 0;
|
|
124
151
|
suspense?.();
|
|
125
152
|
suspense = void 0;
|
|
153
|
+
reset = null;
|
|
154
|
+
pending = queued = false;
|
|
155
|
+
}
|
|
156
|
+
function suspend(on) {
|
|
157
|
+
reset = void 0;
|
|
158
|
+
const suspended = suspense = hold(true, transition);
|
|
159
|
+
const replay = () => {
|
|
160
|
+
if (suspense !== suspended) return;
|
|
161
|
+
suspense = void 0;
|
|
162
|
+
suspended(invoke);
|
|
163
|
+
};
|
|
164
|
+
on.then(replay, replay);
|
|
126
165
|
}
|
|
127
166
|
function invoke() {
|
|
128
167
|
if (reset === null || observer(target) === null) return;
|
|
129
168
|
queued = false;
|
|
130
169
|
let ignore = true;
|
|
131
170
|
function onUpdate() {
|
|
132
|
-
events = [...o.events];
|
|
171
|
+
events = queued ? [...new Set([...events, ...o.events])] : [...o.events];
|
|
133
172
|
if (reset === null) return null;
|
|
173
|
+
if (pending) {
|
|
174
|
+
queued = true;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
134
177
|
if (ignore) {
|
|
135
178
|
if (queued) enqueue(invoke, transition, target);
|
|
136
179
|
return;
|
|
@@ -141,62 +184,86 @@ function watch(target, callback, argument, transition) {
|
|
|
141
184
|
unset = void 0;
|
|
142
185
|
enqueue(invoke, transition, target);
|
|
143
186
|
}
|
|
187
|
+
function apply(output, release) {
|
|
188
|
+
ignore = false;
|
|
189
|
+
reset = output === null ? null : invoke;
|
|
190
|
+
unset = (key) => {
|
|
191
|
+
if (typeof output == "function") output(key);
|
|
192
|
+
if (release) release(key);
|
|
193
|
+
};
|
|
194
|
+
}
|
|
144
195
|
function run(release) {
|
|
145
196
|
if (previous !== latest) unobserve(latest);
|
|
146
197
|
const proxy = observe(target, onUpdate, argument === true);
|
|
147
198
|
const current = latest = proxy[Observing];
|
|
148
199
|
const output = callback.call(proxy, proxy, events);
|
|
149
200
|
if (observer(target) === null) {
|
|
150
|
-
if (typeof output == "function") output(null);
|
|
151
201
|
if (release) release(null);
|
|
152
|
-
|
|
202
|
+
if (output instanceof Promise) output.catch(() => {});
|
|
203
|
+
else if (typeof output == "function") output(null);
|
|
204
|
+
return fail("is destroyed.");
|
|
153
205
|
}
|
|
154
206
|
if (previous && argument === false && !current.watching.size) previous.callback = onUpdate;
|
|
155
207
|
else {
|
|
156
208
|
if (previous) unobserve(previous);
|
|
157
209
|
previous = current;
|
|
158
210
|
}
|
|
159
|
-
ignore = false;
|
|
160
|
-
reset = output === null ? null : invoke;
|
|
161
|
-
unset = (key) => {
|
|
162
|
-
if (typeof output == "function") output(key);
|
|
163
|
-
if (release) release(key);
|
|
164
|
-
};
|
|
165
211
|
events = [];
|
|
212
|
+
if (!(output instanceof Promise)) {
|
|
213
|
+
apply(output, release);
|
|
214
|
+
return conclude(true, void 0);
|
|
215
|
+
}
|
|
216
|
+
pending = true;
|
|
217
|
+
reset = invoke;
|
|
218
|
+
unset = release;
|
|
219
|
+
output.then((value) => {
|
|
220
|
+
pending = false;
|
|
221
|
+
if (reset === null) return;
|
|
222
|
+
apply(void 0, release);
|
|
223
|
+
conclude(true, value);
|
|
224
|
+
if (queued) onUpdate();
|
|
225
|
+
}, (err) => {
|
|
226
|
+
pending = false;
|
|
227
|
+
if (reset === null) return;
|
|
228
|
+
if (err instanceof Promise) return suspend(err);
|
|
229
|
+
queued = false;
|
|
230
|
+
conclude(false, err);
|
|
231
|
+
if (!awaiting) REPORT.as("effect", target, err);
|
|
232
|
+
});
|
|
166
233
|
}
|
|
167
234
|
try {
|
|
168
235
|
if (argument !== false) capture(run);
|
|
169
236
|
else run();
|
|
170
237
|
} catch (err) {
|
|
171
|
-
if (err instanceof Promise)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const replay = () => {
|
|
175
|
-
if (suspense !== suspended) return;
|
|
176
|
-
suspense = void 0;
|
|
177
|
-
suspended(invoke);
|
|
178
|
-
};
|
|
179
|
-
err.then(replay, replay);
|
|
180
|
-
} else throw err;
|
|
238
|
+
if (err instanceof Promise) return suspend(err);
|
|
239
|
+
conclude(false, err);
|
|
240
|
+
if (!awaiting) throw err;
|
|
181
241
|
}
|
|
182
242
|
}
|
|
183
243
|
const unlisten = listener(target, (key) => {
|
|
184
244
|
if (key === true) invoke();
|
|
185
245
|
else if (key === null) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
reset = null;
|
|
246
|
+
stop(null);
|
|
247
|
+
fail("is destroyed.");
|
|
189
248
|
} else if (!reset) {
|
|
190
249
|
suspense?.(false);
|
|
191
250
|
return reset;
|
|
192
251
|
}
|
|
193
252
|
});
|
|
194
253
|
function cleanup() {
|
|
195
|
-
|
|
196
|
-
resume();
|
|
197
|
-
reset = null;
|
|
254
|
+
stop(false);
|
|
198
255
|
unlisten();
|
|
256
|
+
fail("effect was cancelled before it settled.");
|
|
199
257
|
}
|
|
258
|
+
cleanup.then = ((onFulfilled, onRejected) => {
|
|
259
|
+
if (!awaiting) {
|
|
260
|
+
awaiting = new Promise((resolve, reject) => {
|
|
261
|
+
settle = () => outcome.ok ? resolve(outcome.value) : reject(outcome.value);
|
|
262
|
+
});
|
|
263
|
+
if (outcome && !pending && !queued && !suspense) finish();
|
|
264
|
+
}
|
|
265
|
+
return awaiting.then(onFulfilled, onRejected);
|
|
266
|
+
});
|
|
200
267
|
if (EffectContext && argument !== false) EffectContext.add(cleanup);
|
|
201
268
|
return cleanup;
|
|
202
269
|
}
|
package/dist/observable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observable.js","names":[],"sources":["../src/observable.ts"],"sourcesContent":["import { enqueue, hold } from './dispatch';\n\ndeclare namespace Observer {\n /**\n * Update callback function.\n *\n * @param key -\n * - `string` - property which has updated.\n * - `false` - a normal update has completed.\n * - `true` - initial event; instance is ready.\n * - `null` - terminal event; instance is expired.\n */\n type Notify = (key: Signal) => (() => void) | null | void;\n\n type EffectCleanup = (update: boolean | null) => void;\n\n type Effect<T extends object> = (\n this: T,\n proxy: T,\n changed: readonly Event[]\n ) => EffectCleanup | Promise<void> | null | void;\n\n type Event = number | string | symbol;\n\n type Signal = Event | true | false | null;\n\n type Callback = () => void | null;\n}\n\ninterface Observer {\n /** Becomes `true` once the subject has emitted its initial event. */\n ready?: true;\n listeners: Map<Observer.Notify, Set<Observer.Signal> | undefined>;\n /** Recursion guard for an in-progress emit pass. */\n pending: Set<Observer.Signal>;\n /** Accumulator drained by the next microtask. */\n events: Set<Observer.Event>;\n}\n\ninterface Observing {\n callback: Observer.Callback;\n watching: Set<Observer.Signal>;\n required?: boolean;\n release: (() => void)[];\n}\n\nconst Observer: unique symbol = Symbol('Observer');\nconst Observing: unique symbol = Symbol('Observing');\n\n/** Event every observer treats as watched, to force a refresh. */\nconst REFRESH = Symbol.for('@expressive/mvc.refresh');\n\ninterface Observable { [Observer]?: Observer | null }\ninterface Observed { [Observing]?: Observing }\n\n/**\n * Fetch the dispatch bundle attached to an object.\n * - returns the bundle if active\n * - returns `null` if the subject has been terminated\n * - returns `undefined` if the subject was never observable\n *\n * With `create: true`, attaches a fresh bundle iff the slot is undefined.\n * A terminated (null) slot is not resurrected.\n */\nfunction observer(state: object, create: true): Observer;\nfunction observer(state: object, create?: boolean): Observer | undefined | null;\nfunction observer(state: object, create?: boolean) {\n const o = (state as Observable)[Observer];\n\n if (!o && create) {\n if (o === null)\n throw new Error(\n `${state} was destroyed - cannot be rendered, watched or updated.`\n );\n\n const value: Observer = {\n listeners: new Map(),\n pending: new Set(),\n events: new Set()\n };\n Object.defineProperty(state, Observer, { value, writable: true });\n return value;\n }\n\n return o;\n}\n\nfunction observe<T extends object>(\n object: T,\n callback: Observer.Callback,\n required?: boolean,\n cleanup: (() => void)[] = []\n): T {\n const watching = new Set<Observer.Signal>();\n const observing: Observing = { callback, watching, required, release: cleanup };\n\n const release = listener(object, (key) => {\n if (watching.has(key) || key === REFRESH) return observing.callback();\n });\n\n cleanup.push(release);\n\n if (EffectContext)\n EffectContext.add((update) => {\n if (update !== true) release();\n });\n\n const proxy = Object.create(object) as T;\n\n if ('is' in object)\n Object.defineProperty(proxy, 'is', {\n value: (object as { is?: unknown }).is,\n writable: true\n });\n\n return Object.defineProperty(proxy, Observing, { value: observing });\n}\n\nfunction touch(from: object, key: any): void;\nfunction touch<T>(from: object, key: any, value?: T): T;\nfunction touch(from: object, key: any, value?: any) {\n const active = (from as Observed)[Observing];\n\n if (active) {\n if (value === undefined && arguments.length === 3 && active.required)\n throw new Error(\n `${Object.getPrototypeOf(from)}.${String(key)} is required in this context.`\n );\n\n active.watching.add(key);\n\n if (value instanceof Object && observer(value))\n return observe(\n value,\n () => active.callback(),\n active.required,\n active.release\n );\n }\n\n return value;\n}\n\nfunction unobserve(observing: Observing) {\n for (const release of observing.release) release();\n}\n\nfunction listener<T extends object>(\n subject: T,\n callback: Observer.Notify,\n select?: Observer.Signal | Set<Observer.Signal>\n) {\n const o = observer(subject, true);\n\n if (select !== undefined && !(select instanceof Set))\n select = new Set([select]);\n\n if (o.ready && !select) callback(true);\n\n o.listeners.set(callback, select);\n\n return () => o.listeners.delete(callback);\n}\n\nconst EMPTY = Object.assign([], {\n then: Promise.prototype.then.bind(Promise.resolve([]))\n} as PromiseLike<never[]>);\n\nfunction queued<K extends Observer.Event>(\n state: object\n): K[] & PromiseLike<K[]> {\n const o = observer(state);\n if (!o?.events.size) return EMPTY;\n\n const current = o.events as Set<K>;\n const promise = new Promise<K[]>((res) => {\n const callback: Observer.Notify = () => {\n o.listeners.delete(callback);\n return () => res([...current]);\n };\n o.listeners.set(callback, undefined);\n });\n\n return Object.assign([...current], {\n then: promise.then.bind(promise)\n });\n}\n\nfunction event(state: object, key?: Observer.Event | null, silent?: boolean) {\n const o = observer(state, key === undefined);\n\n if (!o) return;\n\n if (key === null) {\n if (!Object.getOwnPropertyDescriptor(state, Observer)) return;\n\n (state as Observable)[Observer] = null;\n return emit(o, key, state);\n }\n\n if (key === undefined) return emit(o, true, state);\n\n if (!o.events.size && !silent)\n enqueue(() => {\n emit(o, false, state);\n o.events = new Set();\n }, undefined, state);\n\n o.events.add(key);\n\n if (!silent) emit(o, key, state);\n}\n\nfunction emit(o: Observer, key: Observer.Signal, subject: object): void {\n const { listeners, pending, ready } = o;\n\n if (key === ready) return;\n\n if (pending.size) {\n pending.add(key);\n return;\n }\n\n if (!ready && key !== null) pending.add(true);\n\n pending.add(key);\n\n for (const k of pending)\n for (const [callback, filter] of listeners)\n if (!filter || filter.has(k)) {\n const after = callback(k);\n if (after === null) listeners.delete(callback);\n else if (typeof after == 'function') enqueue(after, undefined, subject);\n }\n\n if (key === null) listeners.clear();\n else if (key === true) o.ready = true;\n\n pending.clear();\n}\n\n/**\n * Create a side-effect which will update whenever values accessed change.\n * Callback is called immediately and whenever values are stale.\n *\n * @param target - Instance of State to observe.\n * @param callback - Function to invoke when values change.\n * @param requireValues - If `true` will throw if accessing a value which is `undefined`.\n */\nfunction watch<T extends object>(\n target: T,\n callback: Observer.Effect<Required<T>>,\n requireValues: true,\n transition?: (work: () => void) => void\n): () => void;\n\nfunction watch<T extends object>(\n target: T,\n callback: Observer.Effect<T>,\n recursive?: boolean,\n transition?: (work: () => void) => void\n): () => void;\n\nfunction watch<T extends object>(\n target: T,\n callback: Observer.Effect<T>,\n argument?: boolean,\n transition?: (work: () => void) => void\n) {\n const o = observer(target, true);\n let events: readonly Observer.Event[] = [];\n let unset: ((update: boolean | null) => void) | undefined;\n let reset: (() => void) | null | undefined;\n let previous: Observing | undefined;\n let latest: Observing | undefined;\n let queued = false;\n let suspense: ReturnType<typeof hold>;\n\n function resume() {\n suspense?.();\n suspense = undefined;\n }\n\n function invoke() {\n if (reset === null || observer(target) === null) return;\n\n queued = false;\n let ignore: boolean = true;\n\n function onUpdate() {\n events = [...o.events];\n\n if (reset === null) return null;\n if (ignore) {\n if (queued) enqueue(invoke, transition, target);\n return;\n }\n\n ignore = true;\n queued = true;\n\n unset!(true);\n unset = undefined;\n\n enqueue(invoke, transition, target);\n }\n\n function run(release?: (update?: boolean | null) => void) {\n if (previous !== latest) unobserve(latest!);\n\n const proxy = observe(target, onUpdate, argument === true);\n const current = latest = (proxy as Observed)[Observing]!;\n const output = callback.call(proxy, proxy, events);\n\n if (observer(target) === null) {\n if (typeof output == 'function') output(null);\n if (release) release(null);\n return;\n }\n\n if (previous && argument === false && !current.watching.size)\n previous.callback = onUpdate;\n else {\n if (previous) unobserve(previous);\n previous = current;\n }\n\n ignore = false;\n reset = output === null ? null : invoke;\n unset = (key) => {\n if (typeof output == 'function') output(key);\n if (release) release(key);\n };\n\n events = [];\n }\n\n try {\n if (argument !== false) capture(run);\n else run();\n } catch (err) {\n if (err instanceof Promise) {\n reset = undefined;\n const suspended = suspense = hold(true, transition)!;\n const replay = () => {\n if (suspense !== suspended) return;\n suspense = undefined;\n suspended(invoke);\n };\n err.then(replay, replay);\n } else {\n throw err;\n }\n }\n }\n\n const unlisten = listener(target, (key) => {\n if (key === true) invoke();\n else if (key === null) {\n if (unset) unset(null);\n resume();\n reset = null;\n } else if (!reset) {\n suspense?.(false);\n return reset;\n }\n });\n\n function cleanup() {\n if (unset) unset(false);\n\n resume();\n reset = null;\n unlisten();\n }\n\n if (EffectContext && argument !== false) EffectContext.add(cleanup);\n\n return cleanup;\n}\n\nlet EffectContext: Set<(update?: boolean | null) => void> | undefined;\n\nfunction capture(scope: (release: (update?: boolean | null) => void) => void) {\n const parent = EffectContext;\n const context = (EffectContext = new Set());\n\n try {\n scope((update) => context.forEach((fn) => fn(update)));\n } finally {\n EffectContext = parent;\n }\n}\n\nexport {\n listener,\n event,\n Observer,\n touch,\n queued,\n observer,\n watch,\n capture\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"observable.js","names":[],"sources":["../src/observable.ts"],"sourcesContent":["import { enqueue, hold, REPORT } from './dispatch';\n\ndeclare namespace Observer {\n /**\n * Update callback function.\n *\n * @param key -\n * - `string` - property which has updated.\n * - `false` - a normal update has completed.\n * - `true` - initial event; instance is ready.\n * - `null` - terminal event; instance is expired.\n */\n type Notify = (key: Signal) => (() => void) | null | void;\n\n type EffectCleanup = (update: boolean | null) => void;\n\n type EffectOutput = EffectCleanup | null | void;\n\n type Effect<T extends object, R = EffectOutput | Promise<void>> = (\n this: T,\n proxy: T,\n changed: readonly Event[]\n ) => R;\n\n /** Stops the effect when called; awaited, cancels it and yields its value. */\n type Release<R> = (() => void) & PromiseLike<R>;\n\n type Event = number | string | symbol;\n\n type Signal = Event | true | false | null;\n\n type Callback = () => void | null;\n}\n\ninterface Observer {\n /** Becomes `true` once the subject has emitted its initial event. */\n ready?: true;\n listeners: Map<Observer.Notify, Set<Observer.Signal> | undefined>;\n /** Recursion guard for an in-progress emit pass. */\n pending: Set<Observer.Signal>;\n /** Accumulator drained by the next microtask. */\n events: Set<Observer.Event>;\n}\n\ninterface Observing {\n callback: Observer.Callback;\n watching: Set<Observer.Signal>;\n required?: boolean;\n release: (() => void)[];\n}\n\nconst Observer: unique symbol = Symbol('Observer');\nconst Observing: unique symbol = Symbol('Observing');\n\n/** Event every observer treats as watched, to force a refresh. */\nconst REFRESH = Symbol.for('@expressive/mvc.refresh');\n\ninterface Observable { [Observer]?: Observer | null }\ninterface Observed { [Observing]?: Observing }\n\n/**\n * Fetch the dispatch bundle attached to an object.\n * - returns the bundle if active\n * - returns `null` if the subject has been terminated\n * - returns `undefined` if the subject was never observable\n *\n * With `create: true`, attaches a fresh bundle iff the slot is undefined.\n * A terminated (null) slot is not resurrected.\n */\nfunction observer(state: object, create: true): Observer;\nfunction observer(state: object, create?: boolean): Observer | undefined | null;\nfunction observer(state: object, create?: boolean) {\n const o = (state as Observable)[Observer];\n\n if (!o && create) {\n if (o === null)\n throw new Error(\n `${state} was destroyed - cannot be rendered, watched or updated.`\n );\n\n const value: Observer = {\n listeners: new Map(),\n pending: new Set(),\n events: new Set()\n };\n Object.defineProperty(state, Observer, { value, writable: true });\n return value;\n }\n\n return o;\n}\n\nfunction observe<T extends object>(\n object: T,\n callback: Observer.Callback,\n required?: boolean,\n cleanup: (() => void)[] = []\n): T {\n const watching = new Set<Observer.Signal>();\n const observing: Observing = { callback, watching, required, release: cleanup };\n\n const release = listener(object, (key) => {\n if (watching.has(key) || key === REFRESH) return observing.callback();\n });\n\n cleanup.push(release);\n\n if (EffectContext)\n EffectContext.add((update) => {\n if (update !== true) release();\n });\n\n const proxy = Object.create(object) as T;\n\n if ('is' in object)\n Object.defineProperty(proxy, 'is', {\n value: (object as { is?: unknown }).is,\n writable: true\n });\n\n return Object.defineProperty(proxy, Observing, { value: observing });\n}\n\nfunction touch(from: object, key: any): void;\nfunction touch<T>(from: object, key: any, value?: T): T;\nfunction touch(from: object, key: any, value?: any) {\n const active = (from as Observed)[Observing];\n\n if (active) {\n if (value === undefined && arguments.length === 3 && active.required)\n throw new Error(\n `${Object.getPrototypeOf(from)}.${String(key)} is required in this context.`\n );\n\n active.watching.add(key);\n\n if (value instanceof Object && observer(value))\n return observe(\n value,\n () => active.callback(),\n active.required,\n active.release\n );\n }\n\n return value;\n}\n\nfunction unobserve(observing: Observing) {\n for (const release of observing.release) release();\n}\n\nfunction listener<T extends object>(\n subject: T,\n callback: Observer.Notify,\n select?: Observer.Signal | Set<Observer.Signal>\n) {\n const o = observer(subject, true);\n\n if (select !== undefined && !(select instanceof Set))\n select = new Set([select]);\n\n if (o.ready && !select) callback(true);\n\n o.listeners.set(callback, select);\n\n return () => o.listeners.delete(callback);\n}\n\nconst EMPTY = Object.assign([], {\n then: Promise.prototype.then.bind(Promise.resolve([]))\n} as PromiseLike<never[]>);\n\nfunction queued<K extends Observer.Event>(\n state: object\n): K[] & PromiseLike<K[]> {\n const o = observer(state);\n if (!o?.events.size) return EMPTY;\n\n const current = o.events as Set<K>;\n const promise = new Promise<K[]>((res) => {\n const callback: Observer.Notify = () => {\n o.listeners.delete(callback);\n return () => res([...current]);\n };\n o.listeners.set(callback, undefined);\n });\n\n return Object.assign([...current], {\n then: promise.then.bind(promise)\n });\n}\n\nfunction event(state: object, key?: Observer.Event | null, silent?: boolean) {\n const o = observer(state, key === undefined);\n\n if (!o) return;\n\n if (key === null) {\n if (!Object.getOwnPropertyDescriptor(state, Observer)) return;\n\n (state as Observable)[Observer] = null;\n return emit(o, key, state);\n }\n\n if (key === undefined) return emit(o, true, state);\n\n if (!o.events.size && !silent)\n enqueue(() => {\n emit(o, false, state);\n o.events = new Set();\n }, undefined, state);\n\n o.events.add(key);\n\n if (!silent) emit(o, key, state);\n}\n\nfunction emit(o: Observer, key: Observer.Signal, subject: object): void {\n const { listeners, pending, ready } = o;\n\n if (key === ready) return;\n\n if (pending.size) {\n pending.add(key);\n return;\n }\n\n if (!ready && key !== null) pending.add(true);\n\n pending.add(key);\n\n for (const k of pending)\n for (const [callback, filter] of listeners)\n if (!filter || filter.has(k)) {\n const after = callback(k);\n if (after === null) listeners.delete(callback);\n else if (typeof after == 'function') enqueue(after, undefined, subject);\n }\n\n if (key === null) listeners.clear();\n else if (key === true) o.ready = true;\n\n pending.clear();\n}\n\n/**\n * Create a side-effect which will update whenever values accessed change.\n * Callback is called immediately and whenever values are stale.\n *\n * @param target - Instance of Model to observe.\n * @param callback - Function to invoke when values change.\n * @param requireValues - If `true` will throw if accessing a value which is `undefined`.\n */\nfunction watch<T extends object, R = void>(\n target: T,\n callback: Observer.Effect<Required<T>, Observer.EffectOutput | Promise<R>>,\n requireValues: true,\n transition?: (work: () => void) => void\n): Observer.Release<R>;\n\nfunction watch<T extends object, R = void>(\n target: T,\n callback: Observer.Effect<T, Observer.EffectOutput | Promise<R>>,\n recursive?: boolean,\n transition?: (work: () => void) => void\n): Observer.Release<R>;\n\nfunction watch<T extends object, R>(\n target: T,\n callback: Observer.Effect<T, unknown>,\n argument?: boolean,\n transition?: (work: () => void) => void\n): Observer.Release<R> {\n const o = observer(target, true);\n let events: readonly Observer.Event[] = [];\n let unset: ((update: boolean | null) => void) | undefined;\n let reset: (() => void) | null | undefined;\n let previous: Observing | undefined;\n let latest: Observing | undefined;\n let queued = false;\n let pending = false;\n let suspense: ReturnType<typeof hold>;\n let outcome: { ok: boolean; value: unknown } | undefined;\n let awaiting: Promise<R> | undefined;\n let settle: (() => void) | undefined;\n\n function conclude(ok: boolean, value: unknown) {\n outcome = { ok, value };\n if (!ok || !queued) finish();\n }\n\n function finish() {\n const done = awaiting && settle;\n\n if (!done) return;\n\n settle = undefined;\n done();\n cleanup();\n }\n\n function fail(reason: string) {\n if (!outcome) outcome = { ok: false, value: new Error(`${target} ${reason}`) };\n finish();\n }\n\n function stop(key: false | null) {\n if (unset) unset(key);\n unset = undefined;\n suspense?.();\n suspense = undefined;\n reset = null;\n pending = queued = false;\n }\n\n function suspend(on: Promise<unknown>) {\n reset = undefined;\n const suspended = suspense = hold(true, transition)!;\n const replay = () => {\n if (suspense !== suspended) return;\n suspense = undefined;\n suspended(invoke);\n };\n on.then(replay, replay);\n }\n\n function invoke() {\n if (reset === null || observer(target) === null) return;\n\n queued = false;\n let ignore: boolean = true;\n\n function onUpdate() {\n events = queued ? [...new Set([...events, ...o.events])] : [...o.events];\n\n if (reset === null) return null;\n if (pending) {\n queued = true;\n return;\n }\n if (ignore) {\n if (queued) enqueue(invoke, transition, target);\n return;\n }\n\n ignore = true;\n queued = true;\n\n unset!(true);\n unset = undefined;\n\n enqueue(invoke, transition, target);\n }\n\n function apply(output: unknown, release?: (update?: boolean | null) => void) {\n ignore = false;\n reset = output === null ? null : invoke;\n unset = (key) => {\n if (typeof output == 'function') output(key);\n if (release) release(key);\n };\n }\n\n function run(release?: (update?: boolean | null) => void) {\n if (previous !== latest) unobserve(latest!);\n\n const proxy = observe(target, onUpdate, argument === true);\n const current = latest = (proxy as Observed)[Observing]!;\n const output = callback.call(proxy, proxy, events);\n\n if (observer(target) === null) {\n if (release) release(null);\n if (output instanceof Promise) output.catch(() => {});\n else if (typeof output == 'function') output(null);\n return fail('is destroyed.');\n }\n\n if (previous && argument === false && !current.watching.size)\n previous.callback = onUpdate;\n else {\n if (previous) unobserve(previous);\n previous = current;\n }\n\n events = [];\n\n if (!(output instanceof Promise)) {\n apply(output, release);\n return conclude(true, undefined);\n }\n\n pending = true;\n reset = invoke;\n unset = release;\n\n output.then(\n (value) => {\n pending = false;\n\n if (reset === null) return;\n\n apply(undefined, release);\n conclude(true, value);\n\n if (queued) onUpdate();\n },\n (err) => {\n pending = false;\n\n if (reset === null) return;\n if (err instanceof Promise) return suspend(err);\n\n queued = false;\n conclude(false, err);\n\n if (!awaiting) REPORT.as('effect', target, err);\n }\n );\n }\n\n try {\n if (argument !== false) capture(run);\n else run();\n } catch (err) {\n if (err instanceof Promise) return suspend(err);\n\n conclude(false, err);\n\n if (!awaiting) throw err;\n }\n }\n\n const unlisten = listener(target, (key) => {\n if (key === true) invoke();\n else if (key === null) {\n stop(null);\n fail('is destroyed.');\n } else if (!reset) {\n suspense?.(false);\n return reset;\n }\n });\n\n function cleanup() {\n stop(false);\n unlisten();\n\n fail('effect was cancelled before it settled.');\n }\n\n cleanup.then = ((onFulfilled, onRejected) => {\n if (!awaiting) {\n awaiting = new Promise<R>((resolve, reject) => {\n settle = () => (outcome!.ok ? resolve(outcome!.value as R) : reject(outcome!.value));\n });\n\n if (outcome && !pending && !queued && !suspense) finish();\n }\n\n return awaiting.then(onFulfilled, onRejected);\n }) as PromiseLike<R>['then'];\n\n if (EffectContext && argument !== false) EffectContext.add(cleanup);\n\n return cleanup;\n}\n\nlet EffectContext: Set<(update?: boolean | null) => void> | undefined;\n\nfunction capture(scope: (release: (update?: boolean | null) => void) => void) {\n const parent = EffectContext;\n const context = (EffectContext = new Set());\n\n try {\n scope((update) => context.forEach((fn) => fn(update)));\n } finally {\n EffectContext = parent;\n }\n}\n\nexport {\n listener,\n event,\n Observer,\n touch,\n queued,\n observer,\n watch,\n capture\n};\n"],"mappings":"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"}
|