@expressive/mvc 0.85.0 → 0.86.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 +3 -3
- package/dist/caught.d.ts +5237 -0
- package/dist/caught.js +64 -0
- package/dist/caught.js.map +1 -0
- package/dist/context.js +1 -1
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +8 -3
- package/dist/dispatch.js.map +1 -1
- package/dist/field/def.js +1 -1
- package/dist/field/get.js +1 -1
- package/dist/field/has.d.ts +11 -3
- package/dist/field/has.js +1 -1
- package/dist/field/has.js.map +1 -1
- package/dist/field/map.js +1 -1
- package/dist/field/ref.js +1 -1
- package/dist/field/set.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -0
- package/dist/observable.js +25 -14
- package/dist/observable.js.map +1 -1
- package/dist/state.d.ts +14 -3
- package/dist/state.js +55 -13
- package/dist/state.js.map +1 -1
- package/package.json +1 -1
package/dist/caught.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
//#region src/caught.ts
|
|
2
|
+
const about = (cause) => {
|
|
3
|
+
const text = cause instanceof Error ? cause.message : String(cause);
|
|
4
|
+
return text ? `: ${text}` : ".";
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Reported to `State.on({ catch })` handlers instead of being thrown or logged.
|
|
8
|
+
* Unhandled, a `warning` goes to `console.warn`; anything else escapes uncaught.
|
|
9
|
+
*/
|
|
10
|
+
var Caught = class Caught extends Error {
|
|
11
|
+
name = "Caught";
|
|
12
|
+
/** Non-urgent - unhandled, it logs as a warning. */
|
|
13
|
+
warning = false;
|
|
14
|
+
constructor(state, message, key, cause) {
|
|
15
|
+
super(message, arguments.length > 3 ? { cause } : void 0);
|
|
16
|
+
this.key = key;
|
|
17
|
+
Object.defineProperty(this, "state", { value: state });
|
|
18
|
+
}
|
|
19
|
+
/** A `catch` handler logging what would otherwise escape uncaught; warnings and destroyed writes pass on. */
|
|
20
|
+
static log(error) {
|
|
21
|
+
if (error.warning || error instanceof Caught.Destroyed) return error;
|
|
22
|
+
console.error(error);
|
|
23
|
+
}
|
|
24
|
+
/** A write to a destroyed state - thrown to the writer unless a handler takes it. */
|
|
25
|
+
static Destroyed = class Destroyed extends Caught {
|
|
26
|
+
name = "Caught.Destroyed";
|
|
27
|
+
constructor(state, key) {
|
|
28
|
+
super(state, `Tried to update ${state}.${key} but state is destroyed.`, key);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
/** A state constructed but never activated. */
|
|
32
|
+
static Inactive = class Inactive extends Caught {
|
|
33
|
+
name = "Caught.Inactive";
|
|
34
|
+
warning = true;
|
|
35
|
+
constructor(state) {
|
|
36
|
+
super(state, `${state} was constructed but never activated.`);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/** A getter threw while refreshing; `cause` is what it threw. */
|
|
40
|
+
static Getter = class Getter extends Caught {
|
|
41
|
+
name = "Caught.Getter";
|
|
42
|
+
constructor(state, key, cause) {
|
|
43
|
+
super(state, `An exception was thrown while refreshing ${state.constructor}.${key}${about(cause)}`, key, cause);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
/** An async initializer rejected; `cause` is the rejection. */
|
|
47
|
+
static Init = class Init extends Caught {
|
|
48
|
+
name = "Caught.Init";
|
|
49
|
+
constructor(state, cause) {
|
|
50
|
+
super(state, `Async error in constructor for ${state.constructor}${about(cause)}`, void 0, cause);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
/** An effect or listener threw during a dispatch flush; `cause` is what it threw. */
|
|
54
|
+
static Effect = class Effect extends Caught {
|
|
55
|
+
name = "Caught.Effect";
|
|
56
|
+
constructor(state, cause) {
|
|
57
|
+
super(state, `An exception was thrown by an effect of ${state.constructor}${about(cause)}`, void 0, cause);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { Caught };
|
|
64
|
+
//# sourceMappingURL=caught.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caught.js","names":[],"sources":["../src/caught.ts"],"sourcesContent":["import type { State } from './state';\n\nconst about = (cause: unknown) => {\n const text = cause instanceof Error ? cause.message : String(cause);\n return text ? `: ${text}` : '.';\n};\n\n/**\n * Reported to `State.on({ catch })` handlers instead of being thrown or logged.\n * Unhandled, a `warning` goes to `console.warn`; anything else escapes uncaught.\n */\nclass Caught extends Error {\n readonly name: string = 'Caught';\n\n /** Non-urgent - unhandled, it logs as a warning. */\n readonly warning: boolean = false;\n\n declare readonly state: State;\n\n constructor(\n state: State,\n message: string,\n readonly key?: string,\n cause?: unknown\n ) {\n super(message, arguments.length > 3 ? { cause } : undefined);\n Object.defineProperty(this, 'state', { value: state });\n }\n\n /** A `catch` handler logging what would otherwise escape uncaught; warnings and destroyed writes pass on. */\n static log(error: Caught): Caught | void {\n if (error.warning || error instanceof Caught.Destroyed) return error;\n console.error(error);\n }\n\n /** A write to a destroyed state - thrown to the writer unless a handler takes it. */\n static Destroyed = class Destroyed extends Caught {\n readonly name = 'Caught.Destroyed';\n\n constructor(state: State, key: string) {\n super(state, `Tried to update ${state}.${key} but state is destroyed.`, key);\n }\n };\n\n /** A state constructed but never activated. */\n static Inactive = class Inactive extends Caught {\n readonly name = 'Caught.Inactive';\n readonly warning = true;\n\n constructor(state: State) {\n super(state, `${state} was constructed but never activated.`);\n }\n };\n\n /** A getter threw while refreshing; `cause` is what it threw. */\n static Getter = class Getter extends Caught {\n readonly name = 'Caught.Getter';\n\n constructor(state: State, key: string, cause: unknown) {\n super(state, `An exception was thrown while refreshing ${state.constructor}.${key}${about(cause)}`, key, cause);\n }\n };\n\n /** An async initializer rejected; `cause` is the rejection. */\n static Init = class Init extends Caught {\n readonly name = 'Caught.Init';\n\n constructor(state: State, cause: unknown) {\n super(state, `Async error in constructor for ${state.constructor}${about(cause)}`, undefined, cause);\n }\n };\n\n /** An effect or listener threw during a dispatch flush; `cause` is what it threw. */\n static Effect = class Effect extends Caught {\n readonly name = 'Caught.Effect';\n\n constructor(state: State, cause: unknown) {\n super(state, `An exception was thrown by an effect of ${state.constructor}${about(cause)}`, undefined, cause);\n }\n };\n}\n\ndeclare namespace Caught {\n type Destroyed = InstanceType<typeof Caught.Destroyed>;\n type Inactive = InstanceType<typeof Caught.Inactive>;\n type Getter = InstanceType<typeof Caught.Getter>;\n type Init = InstanceType<typeof Caught.Init>;\n type Effect = InstanceType<typeof Caught.Effect>;\n}\n\nexport { Caught };\n"],"mappings":";AAEA,MAAM,SAAS,UAAmB;CAChC,MAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACnE,QAAO,OAAO,KAAK,SAAS;;;;;;AAO9B,IAAM,SAAN,MAAM,eAAe,MAAM;CACzB,AAAS,OAAe;;CAGxB,AAAS,UAAmB;CAI5B,YACE,OACA,SACA,AAAS,KACT,OACA;AACA,QAAM,SAAS,UAAU,SAAS,IAAI,EAAE,OAAO,GAAG,OAAU;EAHnD;AAIT,SAAO,eAAe,MAAM,SAAS,EAAE,OAAO,OAAO,CAAC;;;CAIxD,OAAO,IAAI,OAA8B;AACvC,MAAI,MAAM,WAAW,iBAAiB,OAAO,UAAW,QAAO;AAC/D,UAAQ,MAAM,MAAM;;;CAItB,OAAO,YAAY,MAAM,kBAAkB,OAAO;EAChD,AAAS,OAAO;EAEhB,YAAY,OAAc,KAAa;AACrC,SAAM,OAAO,mBAAmB,MAAM,GAAG,IAAI,2BAA2B,IAAI;;;;CAKhF,OAAO,WAAW,MAAM,iBAAiB,OAAO;EAC9C,AAAS,OAAO;EAChB,AAAS,UAAU;EAEnB,YAAY,OAAc;AACxB,SAAM,OAAO,GAAG,MAAM,uCAAuC;;;;CAKjE,OAAO,SAAS,MAAM,eAAe,OAAO;EAC1C,AAAS,OAAO;EAEhB,YAAY,OAAc,KAAa,OAAgB;AACrD,SAAM,OAAO,4CAA4C,MAAM,YAAY,GAAG,MAAM,MAAM,MAAM,IAAI,KAAK,MAAM;;;;CAKnH,OAAO,OAAO,MAAM,aAAa,OAAO;EACtC,AAAS,OAAO;EAEhB,YAAY,OAAc,OAAgB;AACxC,SAAM,OAAO,kCAAkC,MAAM,cAAc,MAAM,MAAM,IAAI,QAAW,MAAM;;;;CAKxG,OAAO,SAAS,MAAM,eAAe,OAAO;EAC1C,AAAS,OAAO;EAEhB,YAAY,OAAc,OAAgB;AACxC,SAAM,OAAO,2CAA2C,MAAM,cAAc,MAAM,MAAM,IAAI,QAAW,MAAM"}
|
package/dist/context.js
CHANGED
package/dist/dispatch.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ declare function hold(detached?: true, transition?: Transition): Hold | undefine
|
|
|
14
14
|
* subscriber defers - it brackets the replay, but only where the scheduled
|
|
15
15
|
* work asked for one.
|
|
16
16
|
*/
|
|
17
|
-
declare function enqueue(handler: Handler, transition?: Transition): void;
|
|
17
|
+
declare function enqueue(handler: Handler, transition?: Transition, owner?: object): void;
|
|
18
18
|
/**
|
|
19
19
|
* Run `work` now, marking the subscriber updates it queues non-urgent - each
|
|
20
20
|
* replays through whatever scheduler it subscribed with. The callback itself is
|
package/dist/dispatch.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { fault } from "./state.js";
|
|
2
|
+
|
|
1
3
|
//#region src/dispatch.ts
|
|
2
4
|
const DISPATCH = /* @__PURE__ */ new Map();
|
|
3
5
|
let current;
|
|
@@ -57,7 +59,7 @@ function flush() {
|
|
|
57
59
|
if (transition) transition(handler);
|
|
58
60
|
else handler();
|
|
59
61
|
} catch (err) {
|
|
60
|
-
|
|
62
|
+
fault(err, scheduled.owner);
|
|
61
63
|
} finally {
|
|
62
64
|
current = replaying = void 0;
|
|
63
65
|
}
|
|
@@ -69,11 +71,14 @@ function flush() {
|
|
|
69
71
|
* subscriber defers - it brackets the replay, but only where the scheduled
|
|
70
72
|
* work asked for one.
|
|
71
73
|
*/
|
|
72
|
-
function enqueue(handler, transition) {
|
|
74
|
+
function enqueue(handler, transition, owner) {
|
|
73
75
|
if (!DISPATCH.size) queueMicrotask(flush);
|
|
74
76
|
const scheduled = DISPATCH.get(handler);
|
|
75
77
|
if (!scheduled) {
|
|
76
|
-
const next = {
|
|
78
|
+
const next = {
|
|
79
|
+
transition: current ? transition : void 0,
|
|
80
|
+
owner
|
|
81
|
+
};
|
|
77
82
|
DISPATCH.set(handler, next);
|
|
78
83
|
claim(next);
|
|
79
84
|
} else if (current) claim(scheduled);
|
package/dist/dispatch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.js","names":[],"sources":["../src/dispatch.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"dispatch.js","names":[],"sources":["../src/dispatch.ts"],"sourcesContent":["import { fault } from './state';\n\ntype Handler = () => void;\ntype Transition = (work: Handler) => void;\n\ninterface Pending {\n count: number;\n done(): void;\n}\n\ntype Hold = (retry?: Handler | false) => void;\n\ninterface Scheduled {\n /** How this subscriber defers, if it can - supplied where it subscribed. */\n transition?: Transition;\n awaiting?: Set<Pending>;\n holds?: number;\n owner?: object;\n}\n\nconst DISPATCH = new Map<Handler, Scheduled>();\nlet current: Iterable<Pending> | undefined;\nlet replaying: Scheduled | undefined;\n\n/**\n * Await this handler's replay for the work being scheduled. Overlapping calls\n * may each be waiting on the same handler, which replays once.\n */\nfunction claim(scheduled: Scheduled) {\n if (!current) return;\n\n const awaiting = scheduled.awaiting || (scheduled.awaiting = new Set());\n\n for (const record of current)\n if (!awaiting.has(record)) {\n awaiting.add(record);\n record.count++;\n }\n}\n\nfunction drop(scheduled: Scheduled) {\n const { awaiting } = scheduled;\n\n if (!awaiting) return;\n\n scheduled.awaiting = undefined;\n\n for (const record of awaiting)\n if (!--record.count) record.done();\n}\n\n/**\n * Hold the work being replayed until the returned callback runs - a subscriber\n * which has not yet absorbed the update takes one, and settlement waits on it\n * rather than on the replay. Returns nothing unless the replay carries pending\n * work, so an unrelated subscriber pays for none of it.\n */\nfunction hold(detached?: true, transition?: Transition) {\n const scheduled = replaying || {};\n\n if (detached) {\n scheduled.transition = transition;\n claim(scheduled);\n }\n else if (!scheduled.awaiting) return;\n\n let released = false;\n\n scheduled.holds = (scheduled.holds || 0) + 1;\n\n const release: Hold = (retry) => {\n if (released) return;\n if (retry === false) return claim(scheduled);\n\n if (retry) {\n current = scheduled.awaiting;\n enqueue(retry, scheduled.transition);\n current = undefined;\n }\n\n released = true;\n if (!--scheduled.holds!) drop(scheduled);\n };\n\n return release;\n}\n\nfunction flush() {\n for (const [handler, scheduled] of DISPATCH) {\n DISPATCH.delete(handler);\n\n const { awaiting, transition } = scheduled;\n\n current = awaiting;\n replaying = scheduled;\n\n try {\n if (transition) transition(handler);\n else handler();\n } catch (err) {\n fault(err, scheduled.owner);\n } finally {\n current = replaying = undefined;\n }\n\n if (!scheduled.holds) drop(scheduled);\n }\n}\n\n/**\n * Queue `handler` to replay after this tick. `transition` is how this\n * subscriber defers - it brackets the replay, but only where the scheduled\n * work asked for one.\n */\nfunction enqueue(handler: Handler, transition?: Transition, owner?: object) {\n if (!DISPATCH.size) queueMicrotask(flush);\n\n const scheduled = DISPATCH.get(handler);\n\n if (!scheduled) {\n const next: Scheduled = {\n transition: current ? transition : undefined,\n owner\n };\n\n DISPATCH.set(handler, next);\n claim(next);\n } else if (current) {\n claim(scheduled);\n } else {\n scheduled.transition = undefined;\n }\n}\n\n/**\n * Run `work` now, marking the subscriber updates it queues non-urgent - each\n * replays through whatever scheduler it subscribed with. The callback itself is\n * synchronous; only what it notifies is pending.\n *\n * Resolves once every one of those updates has replayed and been absorbed. A\n * subscriber which cannot report absorption resolves on replay; one which can\n * defer brackets its own replay.\n */\nfunction pending(work: Handler): Promise<void>;\n\n/**\n * Declare the subscriber currently replaying has not absorbed its update yet -\n * settlement waits on the returned callback rather than on the replay. Call\n * only from inside a replay carrying pending work; elsewhere this returns\n * nothing and the subscriber pays for none of it.\n */\nfunction pending(): (() => void) | undefined;\n\nfunction pending(work?: Handler): Promise<void> | (() => void) | undefined {\n if (!work) return hold();\n\n const parent = current;\n const record = { count: 1 } as Pending;\n const promise = new Promise<void>((resolve) => {\n record.done = resolve;\n });\n\n current = parent ? [...parent, record] : [record];\n\n try {\n work();\n } finally {\n current = parent;\n if (!--record.count) record.done();\n }\n\n return promise;\n}\n\nexport { enqueue, hold, pending };\n"],"mappings":";;;AAoBA,MAAM,2BAAW,IAAI,KAAyB;AAC9C,IAAI;AACJ,IAAI;;;;;AAMJ,SAAS,MAAM,WAAsB;AACnC,KAAI,CAAC,QAAS;CAEd,MAAM,WAAW,UAAU,aAAa,UAAU,2BAAW,IAAI,KAAK;AAEtE,MAAK,MAAM,UAAU,QACnB,KAAI,CAAC,SAAS,IAAI,OAAO,EAAE;AACzB,WAAS,IAAI,OAAO;AACpB,SAAO;;;AAIb,SAAS,KAAK,WAAsB;CAClC,MAAM,EAAE,aAAa;AAErB,KAAI,CAAC,SAAU;AAEf,WAAU,WAAW;AAErB,MAAK,MAAM,UAAU,SACnB,KAAI,CAAC,EAAE,OAAO,MAAO,QAAO,MAAM;;;;;;;;AAStC,SAAS,KAAK,UAAiB,YAAyB;CACtD,MAAM,YAAY,aAAa,EAAE;AAEjC,KAAI,UAAU;AACZ,YAAU,aAAa;AACvB,QAAM,UAAU;YAET,CAAC,UAAU,SAAU;CAE9B,IAAI,WAAW;AAEf,WAAU,SAAS,UAAU,SAAS,KAAK;CAE3C,MAAM,WAAiB,UAAU;AAC/B,MAAI,SAAU;AACd,MAAI,UAAU,MAAO,QAAO,MAAM,UAAU;AAE5C,MAAI,OAAO;AACT,aAAU,UAAU;AACpB,WAAQ,OAAO,UAAU,WAAW;AACpC,aAAU;;AAGZ,aAAW;AACX,MAAI,CAAC,EAAE,UAAU,MAAQ,MAAK,UAAU;;AAG1C,QAAO;;AAGT,SAAS,QAAQ;AACf,MAAK,MAAM,CAAC,SAAS,cAAc,UAAU;AAC3C,WAAS,OAAO,QAAQ;EAExB,MAAM,EAAE,UAAU,eAAe;AAEjC,YAAU;AACV,cAAY;AAEZ,MAAI;AACF,OAAI,WAAY,YAAW,QAAQ;OAC9B,UAAS;WACP,KAAK;AACZ,SAAM,KAAK,UAAU,MAAM;YACnB;AACR,aAAU,YAAY;;AAGxB,MAAI,CAAC,UAAU,MAAO,MAAK,UAAU;;;;;;;;AASzC,SAAS,QAAQ,SAAkB,YAAyB,OAAgB;AAC1E,KAAI,CAAC,SAAS,KAAM,gBAAe,MAAM;CAEzC,MAAM,YAAY,SAAS,IAAI,QAAQ;AAEvC,KAAI,CAAC,WAAW;EACd,MAAM,OAAkB;GACtB,YAAY,UAAU,aAAa;GACnC;GACD;AAED,WAAS,IAAI,SAAS,KAAK;AAC3B,QAAM,KAAK;YACF,QACT,OAAM,UAAU;KAEhB,WAAU,aAAa;;AAuB3B,SAAS,QAAQ,MAA0D;AACzE,KAAI,CAAC,KAAM,QAAO,MAAM;CAExB,MAAM,SAAS;CACf,MAAM,SAAS,EAAE,OAAO,GAAG;CAC3B,MAAM,UAAU,IAAI,SAAe,YAAY;AAC7C,SAAO,OAAO;GACd;AAEF,WAAU,SAAS,CAAC,GAAG,QAAQ,OAAO,GAAG,CAAC,OAAO;AAEjD,KAAI;AACF,QAAM;WACE;AACR,YAAU;AACV,MAAI,CAAC,EAAE,OAAO,MAAO,QAAO,MAAM;;AAGpC,QAAO"}
|
package/dist/field/def.js
CHANGED
package/dist/field/get.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { capture, listener, observer } from "../observable.js";
|
|
2
1
|
import { STORE, children, parent, update } from "../state.js";
|
|
2
|
+
import { capture, listener, observer } from "../observable.js";
|
|
3
3
|
import { Context } from "../context.js";
|
|
4
4
|
import { def } from "./def.js";
|
|
5
5
|
|
package/dist/field/has.d.ts
CHANGED
|
@@ -4,11 +4,11 @@ import { State } from "../state.js";
|
|
|
4
4
|
type Predicate<T> = (value: T, index: number, self: unknown) => boolean;
|
|
5
5
|
type Mapper<T, U> = (value: T, index: number, self: unknown) => U;
|
|
6
6
|
declare namespace has {
|
|
7
|
-
export { Predicate, Mapper, List, Pool };
|
|
7
|
+
export { Predicate, Mapper, List, Pool, Create, From };
|
|
8
8
|
}
|
|
9
9
|
declare function has<T>(initial?: Iterable<T> | false | null): List<T>;
|
|
10
|
-
declare function has<T extends State>(Type: new (...args: State.Args<T>) => T):
|
|
11
|
-
declare function has<T extends State, K extends State.Field<T>>(Type: new (...args: State.Args<T>) => T, fromKey: K):
|
|
10
|
+
declare function has<T extends State>(Type: new (...args: State.Args<T>) => T): Create<T>;
|
|
11
|
+
declare function has<T extends State, K extends State.Field<T>>(Type: new (...args: State.Args<T>) => T, fromKey: K): From<T, K>;
|
|
12
12
|
declare function has<R, A extends unknown[]>(make: (...args: A) => R): Pool<Exclude<R, null | undefined>, A, R>;
|
|
13
13
|
declare class List<T> {
|
|
14
14
|
constructor(initial?: Iterable<T> | false | null);
|
|
@@ -31,6 +31,14 @@ declare class List<T> {
|
|
|
31
31
|
any(fn: Predicate<T>): boolean;
|
|
32
32
|
all(fn: Predicate<T>): boolean;
|
|
33
33
|
}
|
|
34
|
+
interface Create<T extends State> extends Pool<T, State.Args<T>> {
|
|
35
|
+
add(...args: State.Args<T>): T;
|
|
36
|
+
add(instance: T): T;
|
|
37
|
+
}
|
|
38
|
+
interface From<T extends State, K extends State.Field<T>> extends Pool<T, [from: T[K]]> {
|
|
39
|
+
add(from: T[K]): T;
|
|
40
|
+
add(instance: T): T;
|
|
41
|
+
}
|
|
34
42
|
declare class Pool<T, A extends unknown[] = unknown[], R = T> {
|
|
35
43
|
constructor(make: Function, fromKey?: string);
|
|
36
44
|
get size(): number;
|
package/dist/field/has.js
CHANGED
package/dist/field/has.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"has.js","names":[],"sources":["../../src/field/has.ts"],"sourcesContent":["import { Context } from '../context';\nimport { event, listener, touch } from '../observable';\nimport { State, parent } from '../state';\nimport { def } from './def';\n\nconst LENGTH = Symbol('length');\nconst SHAPE = Symbol('shape');\n\nconst ITEMS = new WeakMap<object, unknown[]>();\nconst MEMBERS = new WeakMap<object, Set<unknown>>();\nconst OWNED = new WeakMap<object, Map<unknown, () => void>>();\nconst MAKE = new WeakMap<object, Make>();\n\ntype Make = (...args: unknown[]) => unknown;\ntype Predicate<T> = (value: T, index: number, self: unknown) => boolean;\ntype Mapper<T, U> = (value: T, index: number, self: unknown) => U;\n\ndeclare namespace has {\n export { Predicate, Mapper, List, Pool }\n}\n\nfunction has<T>(initial?: Iterable<T> | false | null): List<T>;\n\nfunction has<T extends State>(\n Type: new (...args: State.Args<T>) => T\n): Pool<T, State.Args<T> | [T]>;\n\nfunction has<T extends State, K extends State.Field<T>>(\n Type: new (...args: State.Args<T>) => T,\n fromKey: K\n): Pool<T, [T[K]] | [T]>;\n\nfunction has<R, A extends unknown[]>(\n make: (...args: A) => R\n): Pool<Exclude<R, null | undefined>, A, R>;\n\nfunction has(\n arg?: Iterable<unknown> | Function | false | null,\n fromKey?: string\n): unknown {\n return def((_key, subject) => {\n const value =\n typeof arg == 'function' ? new Pool(arg, fromKey) : new List(arg);\n\n parent(value, subject);\n listener(subject, () => value.clear(), null);\n\n return { set: false, value };\n });\n}\n\nclass List<T> {\n constructor(initial?: Iterable<T> | false | null) {\n ITEMS.set(this, initial ? Array.from(initial) : []);\n OWNED.set(this, new Map());\n\n event(this);\n }\n\n get size(): number {\n return touch(this, LENGTH, items<T>(this).length);\n }\n\n get(): State.Export<T>[];\n get(index: number): T | undefined;\n get(start: number, end: number): T[];\n get(predicate: Predicate<T>): T | undefined;\n get(arg?: number | Predicate<T>, second?: number): any {\n const values = items<T>(this);\n\n if (arg === undefined) return values.map(exportValue);\n\n if (typeof arg === 'function') return findOf(this, arg);\n\n if (typeof second !== 'number') {\n const at = arg < 0 ? values.length + arg : arg;\n\n return at < 0 || at >= values.length\n ? touch(this, LENGTH)\n : touch(this, at, values[at]);\n }\n\n touch(this, LENGTH);\n\n const start = arg < 0 ? Math.max(values.length + arg, 0) : arg;\n\n return values\n .slice(start, Math.min(second, values.length))\n .map((v, i) => touch(this, start + i, v));\n }\n\n set(index: number, value: T) {\n const target = source(this);\n const values = ITEMS.get(target) as T[];\n const at = index < 0 ? values.length + index : index;\n\n if (at < 0 || at >= values.length || values[at] === value) return;\n\n values[at] = value;\n event(target, at);\n }\n\n put(index: number, ...values: T[]) {\n if (!values.length) return;\n\n const target = source(this);\n const arr = ITEMS.get(target) as T[];\n const at =\n index < 0\n ? Math.max(arr.length + index, 0)\n : Math.min(index, arr.length);\n\n arr.splice(at, 0, ...values);\n\n for (let i = at; i < arr.length; i++) event(target, i);\n event(target, LENGTH);\n }\n\n push(...values: T[]): number {\n this.put(items(this).length, ...values);\n return items(this).length;\n }\n\n pop(): T | undefined;\n pop(index: number): T | undefined;\n pop(index: number, count: number): T[];\n pop(index = -1, count?: number): T | T[] | undefined {\n const target = source(this);\n const values = ITEMS.get(target) as T[];\n const before = values.length;\n const start =\n index < 0 ? Math.max(before + index, 0) : Math.min(index, before);\n const removed = values.splice(start, count ?? 1);\n\n if (removed.length) {\n const end = Math.max(before, values.length);\n for (let i = start; i < end; i++) event(target, i);\n event(target, LENGTH);\n }\n\n return count === undefined ? removed[0] : removed;\n }\n\n clear() {\n this.pop(0, items(this).length);\n }\n\n *[Symbol.iterator](): IterableIterator<T> {\n const values = items<T>(this);\n\n touch(this, LENGTH);\n\n for (let i = 0; i < values.length; i++) yield touch(this, i, values[i]);\n }\n\n map<U>(fn: Mapper<T, U>): U[];\n map<U, X extends U>(fn: Mapper<T, U>, ignore: X): Exclude<U, X>[];\n map<U>(fn: Mapper<T, U>, ignore?: U): U[] {\n return mapOf(this, fn, arguments.length > 1, ignore);\n }\n\n filter(fn: Predicate<T>): T[] {\n return filterOf(this, fn);\n }\n\n any(fn: Predicate<T>): boolean {\n return anyOf(this, fn);\n }\n\n all(fn: Predicate<T>): boolean {\n return !anyOf(this, (v, i, self) => !fn(v, i, self));\n }\n}\n\nclass Pool<T, A extends unknown[] = unknown[], R = T> {\n constructor(make: Function, fromKey?: string) {\n if (State.is(make)) {\n const Type = make as unknown as State.Type;\n\n make = (...args: State.Args) =>\n args.length == 1 && args[0] instanceof Type ? args[0] :\n fromKey ? new Type({ [fromKey]: args[0] }) :\n new Type(...args);\n }\n\n MEMBERS.set(this, new Set());\n MAKE.set(this, make as Make);\n OWNED.set(this, new Map());\n\n event(this);\n }\n\n get size(): number {\n return touch(this, SHAPE, members<T>(this).size);\n }\n\n add(...args: A): R {\n const target = source(this);\n const made = MAKE.get(target)!(...args) as T | null | undefined;\n\n if (made == null) return made as R;\n\n const values = MEMBERS.get(target) as Set<T>;\n\n if (!values.has(made)) {\n values.add(made);\n adopt(target, made, made);\n event(target, made as never);\n event(target, SHAPE);\n }\n\n return made as R;\n }\n\n get(): State.Export<T>[];\n get(predicate: Predicate<T>): T | undefined;\n get(predicate?: Predicate<T>): any {\n return predicate\n ? findOf(this, predicate)\n : Array.from(members<T>(this), exportValue);\n }\n\n has(value: T): boolean {\n return touch(this, value, members<T>(this).has(value));\n }\n\n delete(value: T): boolean {\n const target = source(this);\n const values = MEMBERS.get(target) as Set<T>;\n\n if (!values.has(value)) return false;\n\n release(target, value);\n values.delete(value);\n\n event(target, value as never);\n event(target, SHAPE);\n\n return true;\n }\n\n clear() {\n const target = source(this);\n const values = MEMBERS.get(target) as Set<T>;\n\n if (!values.size) return;\n\n const removed = Array.from(values);\n\n for (const value of removed) release(target, value);\n\n values.clear();\n\n for (const value of removed) event(target, value as never);\n event(target, SHAPE);\n }\n\n *[Symbol.iterator](): IterableIterator<T> {\n const values = members<T>(this);\n\n touch(this, SHAPE);\n\n for (const value of values) yield touch(this, value, value);\n }\n\n map<U>(fn: Mapper<T, U>): U[];\n map<U, X extends U>(fn: Mapper<T, U>, ignore: X): Exclude<U, X>[];\n map<U>(fn: Mapper<T, U>, ignore?: U): U[] {\n return mapOf(this, fn, arguments.length > 1, ignore);\n }\n\n filter(fn: Predicate<T>): T[] {\n return filterOf(this, fn);\n }\n\n any(fn: Predicate<T>): boolean {\n return anyOf(this, fn);\n }\n\n all(fn: Predicate<T>): boolean {\n return !anyOf(this, (v, i, self) => !fn(v, i, self));\n }\n}\n\nfunction source<T extends object>(from: T): T {\n return OWNED.has(from) ? from : Object.getPrototypeOf(from);\n}\n\nfunction adopt(\n target: { delete(key: never): boolean },\n key: unknown,\n value: unknown\n) {\n if (!(value instanceof State)) return;\n\n const owner = parent(target as object);\n const fresh = parent(value, owner ?? null);\n const evict = listener(value, () => void target.delete(key as never), null);\n\n let detach: (() => void) | undefined;\n\n if (fresh && owner)\n detach = Context.get(owner).add(value);\n\n OWNED.get(target)!.set(key, () => {\n evict();\n if (detach) detach();\n if (fresh) value.set(null);\n });\n\n if (fresh) event(value);\n}\n\nfunction release(target: object, key: unknown) {\n const owned = OWNED.get(target)!;\n const free = owned.get(key);\n\n if (free) {\n owned.delete(key);\n free();\n }\n}\n\nfunction exportValue(value: any) {\n return value && typeof value === 'object' && typeof value.get === 'function'\n ? value.get()\n : value;\n}\n\nfunction items<T>(from: object): T[] {\n return ITEMS.get(source(from)) as T[];\n}\n\nfunction members<T>(from: object): Set<T> {\n return MEMBERS.get(source(from)) as Set<T>;\n}\n\nfunction findOf<T>(\n self: Iterable<T>,\n fn: Predicate<T>\n): T | undefined {\n let i = 0;\n\n for (const value of self)\n if (fn(value, i++, self)) return value;\n}\n\nfunction anyOf<T>(self: Iterable<T>, fn: Predicate<T>): boolean {\n let i = 0;\n\n for (const value of self)\n if (fn(value, i++, self)) return true;\n\n return false;\n}\n\nfunction mapOf<T, U>(\n self: Iterable<T>,\n fn: Mapper<T, U>,\n skip: boolean,\n ignore?: U\n): U[] {\n const out: U[] = [];\n let i = 0;\n\n for (const value of self) {\n const result = fn(value, i++, self);\n if (skip && result === ignore) continue;\n out.push(result);\n }\n\n return out;\n}\n\nfunction filterOf<T>(self: Iterable<T>, fn: Predicate<T>): T[] {\n const out: T[] = [];\n let i = 0;\n\n for (const value of self) if (fn(value, i++, self)) out.push(value);\n\n return out;\n}\n\nObject.assign(has, { List, Pool });\n\nexport { has };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"has.js","names":[],"sources":["../../src/field/has.ts"],"sourcesContent":["import { Context } from '../context';\nimport { event, listener, touch } from '../observable';\nimport { State, parent } from '../state';\nimport { def } from './def';\n\nconst LENGTH = Symbol('length');\nconst SHAPE = Symbol('shape');\n\nconst ITEMS = new WeakMap<object, unknown[]>();\nconst MEMBERS = new WeakMap<object, Set<unknown>>();\nconst OWNED = new WeakMap<object, Map<unknown, () => void>>();\nconst MAKE = new WeakMap<object, Make>();\n\ntype Make = (...args: unknown[]) => unknown;\ntype Predicate<T> = (value: T, index: number, self: unknown) => boolean;\ntype Mapper<T, U> = (value: T, index: number, self: unknown) => U;\n\ndeclare namespace has {\n export { Predicate, Mapper, List, Pool, Create, From }\n}\n\nfunction has<T>(initial?: Iterable<T> | false | null): List<T>;\n\nfunction has<T extends State>(\n Type: new (...args: State.Args<T>) => T\n): Create<T>;\n\nfunction has<T extends State, K extends State.Field<T>>(\n Type: new (...args: State.Args<T>) => T,\n fromKey: K\n): From<T, K>;\n\nfunction has<R, A extends unknown[]>(\n make: (...args: A) => R\n): Pool<Exclude<R, null | undefined>, A, R>;\n\nfunction has(\n arg?: Iterable<unknown> | Function | false | null,\n fromKey?: string\n): unknown {\n return def((_key, subject) => {\n const value =\n typeof arg == 'function' ? new Pool(arg, fromKey) : new List(arg);\n\n parent(value, subject);\n listener(subject, () => value.clear(), null);\n\n return { set: false, value };\n });\n}\n\nclass List<T> {\n constructor(initial?: Iterable<T> | false | null) {\n ITEMS.set(this, initial ? Array.from(initial) : []);\n OWNED.set(this, new Map());\n\n event(this);\n }\n\n get size(): number {\n return touch(this, LENGTH, items<T>(this).length);\n }\n\n get(): State.Export<T>[];\n get(index: number): T | undefined;\n get(start: number, end: number): T[];\n get(predicate: Predicate<T>): T | undefined;\n get(arg?: number | Predicate<T>, second?: number): any {\n const values = items<T>(this);\n\n if (arg === undefined) return values.map(exportValue);\n\n if (typeof arg === 'function') return findOf(this, arg);\n\n if (typeof second !== 'number') {\n const at = arg < 0 ? values.length + arg : arg;\n\n return at < 0 || at >= values.length\n ? touch(this, LENGTH)\n : touch(this, at, values[at]);\n }\n\n touch(this, LENGTH);\n\n const start = arg < 0 ? Math.max(values.length + arg, 0) : arg;\n\n return values\n .slice(start, Math.min(second, values.length))\n .map((v, i) => touch(this, start + i, v));\n }\n\n set(index: number, value: T) {\n const target = source(this);\n const values = ITEMS.get(target) as T[];\n const at = index < 0 ? values.length + index : index;\n\n if (at < 0 || at >= values.length || values[at] === value) return;\n\n values[at] = value;\n event(target, at);\n }\n\n put(index: number, ...values: T[]) {\n if (!values.length) return;\n\n const target = source(this);\n const arr = ITEMS.get(target) as T[];\n const at =\n index < 0\n ? Math.max(arr.length + index, 0)\n : Math.min(index, arr.length);\n\n arr.splice(at, 0, ...values);\n\n for (let i = at; i < arr.length; i++) event(target, i);\n event(target, LENGTH);\n }\n\n push(...values: T[]): number {\n this.put(items(this).length, ...values);\n return items(this).length;\n }\n\n pop(): T | undefined;\n pop(index: number): T | undefined;\n pop(index: number, count: number): T[];\n pop(index = -1, count?: number): T | T[] | undefined {\n const target = source(this);\n const values = ITEMS.get(target) as T[];\n const before = values.length;\n const start =\n index < 0 ? Math.max(before + index, 0) : Math.min(index, before);\n const removed = values.splice(start, count ?? 1);\n\n if (removed.length) {\n const end = Math.max(before, values.length);\n for (let i = start; i < end; i++) event(target, i);\n event(target, LENGTH);\n }\n\n return count === undefined ? removed[0] : removed;\n }\n\n clear() {\n this.pop(0, items(this).length);\n }\n\n *[Symbol.iterator](): IterableIterator<T> {\n const values = items<T>(this);\n\n touch(this, LENGTH);\n\n for (let i = 0; i < values.length; i++) yield touch(this, i, values[i]);\n }\n\n map<U>(fn: Mapper<T, U>): U[];\n map<U, X extends U>(fn: Mapper<T, U>, ignore: X): Exclude<U, X>[];\n map<U>(fn: Mapper<T, U>, ignore?: U): U[] {\n return mapOf(this, fn, arguments.length > 1, ignore);\n }\n\n filter(fn: Predicate<T>): T[] {\n return filterOf(this, fn);\n }\n\n any(fn: Predicate<T>): boolean {\n return anyOf(this, fn);\n }\n\n all(fn: Predicate<T>): boolean {\n return !anyOf(this, (v, i, self) => !fn(v, i, self));\n }\n}\n\ninterface Create<T extends State> extends Pool<T, State.Args<T>> {\n add(...args: State.Args<T>): T;\n add(instance: T): T;\n}\n\ninterface From<T extends State, K extends State.Field<T>>\n extends Pool<T, [from: T[K]]> {\n add(from: T[K]): T;\n add(instance: T): T;\n}\n\nclass Pool<T, A extends unknown[] = unknown[], R = T> {\n constructor(make: Function, fromKey?: string) {\n if (State.is(make)) {\n const Type = make as unknown as State.Type;\n\n make = (...args: State.Args) =>\n args.length == 1 && args[0] instanceof Type ? args[0] :\n fromKey ? new Type({ [fromKey]: args[0] }) :\n new Type(...args);\n }\n\n MEMBERS.set(this, new Set());\n MAKE.set(this, make as Make);\n OWNED.set(this, new Map());\n\n event(this);\n }\n\n get size(): number {\n return touch(this, SHAPE, members<T>(this).size);\n }\n\n add(...args: A): R {\n const target = source(this);\n const made = MAKE.get(target)!(...args) as T | null | undefined;\n\n if (made == null) return made as R;\n\n const values = MEMBERS.get(target) as Set<T>;\n\n if (!values.has(made)) {\n values.add(made);\n adopt(target, made, made);\n event(target, made as never);\n event(target, SHAPE);\n }\n\n return made as R;\n }\n\n get(): State.Export<T>[];\n get(predicate: Predicate<T>): T | undefined;\n get(predicate?: Predicate<T>): any {\n return predicate\n ? findOf(this, predicate)\n : Array.from(members<T>(this), exportValue);\n }\n\n has(value: T): boolean {\n return touch(this, value, members<T>(this).has(value));\n }\n\n delete(value: T): boolean {\n const target = source(this);\n const values = MEMBERS.get(target) as Set<T>;\n\n if (!values.has(value)) return false;\n\n release(target, value);\n values.delete(value);\n\n event(target, value as never);\n event(target, SHAPE);\n\n return true;\n }\n\n clear() {\n const target = source(this);\n const values = MEMBERS.get(target) as Set<T>;\n\n if (!values.size) return;\n\n const removed = Array.from(values);\n\n for (const value of removed) release(target, value);\n\n values.clear();\n\n for (const value of removed) event(target, value as never);\n event(target, SHAPE);\n }\n\n *[Symbol.iterator](): IterableIterator<T> {\n const values = members<T>(this);\n\n touch(this, SHAPE);\n\n for (const value of values) yield touch(this, value, value);\n }\n\n map<U>(fn: Mapper<T, U>): U[];\n map<U, X extends U>(fn: Mapper<T, U>, ignore: X): Exclude<U, X>[];\n map<U>(fn: Mapper<T, U>, ignore?: U): U[] {\n return mapOf(this, fn, arguments.length > 1, ignore);\n }\n\n filter(fn: Predicate<T>): T[] {\n return filterOf(this, fn);\n }\n\n any(fn: Predicate<T>): boolean {\n return anyOf(this, fn);\n }\n\n all(fn: Predicate<T>): boolean {\n return !anyOf(this, (v, i, self) => !fn(v, i, self));\n }\n}\n\nfunction source<T extends object>(from: T): T {\n return OWNED.has(from) ? from : Object.getPrototypeOf(from);\n}\n\nfunction adopt(\n target: { delete(key: never): boolean },\n key: unknown,\n value: unknown\n) {\n if (!(value instanceof State)) return;\n\n const owner = parent(target as object);\n const fresh = parent(value, owner ?? null);\n const evict = listener(value, () => void target.delete(key as never), null);\n\n let detach: (() => void) | undefined;\n\n if (fresh && owner)\n detach = Context.get(owner).add(value);\n\n OWNED.get(target)!.set(key, () => {\n evict();\n if (detach) detach();\n if (fresh) value.set(null);\n });\n\n if (fresh) event(value);\n}\n\nfunction release(target: object, key: unknown) {\n const owned = OWNED.get(target)!;\n const free = owned.get(key);\n\n if (free) {\n owned.delete(key);\n free();\n }\n}\n\nfunction exportValue(value: any) {\n return value && typeof value === 'object' && typeof value.get === 'function'\n ? value.get()\n : value;\n}\n\nfunction items<T>(from: object): T[] {\n return ITEMS.get(source(from)) as T[];\n}\n\nfunction members<T>(from: object): Set<T> {\n return MEMBERS.get(source(from)) as Set<T>;\n}\n\nfunction findOf<T>(\n self: Iterable<T>,\n fn: Predicate<T>\n): T | undefined {\n let i = 0;\n\n for (const value of self)\n if (fn(value, i++, self)) return value;\n}\n\nfunction anyOf<T>(self: Iterable<T>, fn: Predicate<T>): boolean {\n let i = 0;\n\n for (const value of self)\n if (fn(value, i++, self)) return true;\n\n return false;\n}\n\nfunction mapOf<T, U>(\n self: Iterable<T>,\n fn: Mapper<T, U>,\n skip: boolean,\n ignore?: U\n): U[] {\n const out: U[] = [];\n let i = 0;\n\n for (const value of self) {\n const result = fn(value, i++, self);\n if (skip && result === ignore) continue;\n out.push(result);\n }\n\n return out;\n}\n\nfunction filterOf<T>(self: Iterable<T>, fn: Predicate<T>): T[] {\n const out: T[] = [];\n let i = 0;\n\n for (const value of self) if (fn(value, i++, self)) out.push(value);\n\n return out;\n}\n\nObject.assign(has, { List, Pool });\n\nexport { has };\n"],"mappings":"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"}
|
package/dist/field/map.js
CHANGED
package/dist/field/ref.js
CHANGED
package/dist/field/set.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from "./context.js";
|
|
2
2
|
import { State, unbind } from "./state.js";
|
|
3
|
+
import { Caught } from "./caught.js";
|
|
3
4
|
import { Component } from "./component.js";
|
|
4
5
|
import { pending } from "./dispatch.js";
|
|
5
6
|
import { def } from "./field/def.js";
|
|
@@ -8,4 +9,4 @@ import { has } from "./field/has.js";
|
|
|
8
9
|
import { map } from "./field/map.js";
|
|
9
10
|
import { ref } from "./field/ref.js";
|
|
10
11
|
import { set } from "./field/set.js";
|
|
11
|
-
export { Component, Context, State, def, State as default, get, has, map, pending, ref, set, unbind };
|
|
12
|
+
export { Caught, Component, Context, State, def, State as default, get, has, map, pending, ref, set, unbind };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Caught } from "./caught.js";
|
|
2
2
|
import { State, unbind } from "./state.js";
|
|
3
|
+
import { pending } from "./dispatch.js";
|
|
3
4
|
import { Context } from "./context.js";
|
|
4
5
|
import { def } from "./field/def.js";
|
|
5
6
|
import { set } from "./field/set.js";
|
|
@@ -9,4 +10,10 @@ import { has } from "./field/has.js";
|
|
|
9
10
|
import { map } from "./field/map.js";
|
|
10
11
|
import { ref } from "./field/ref.js";
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
//#region src/index.ts
|
|
14
|
+
/** @deprecated Import `{ State }` as a named export. Adapter-augmented `State.*` types are not visible through the default alias. */
|
|
15
|
+
var src_default = State;
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Caught, Component, Context, State, def, src_default as default, get, has, map, pending, ref, set, unbind };
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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 { State } from './state';\n\nexport { State, unbind } from './state';\n\n/** @deprecated Import `{ State }` as a named export. Adapter-augmented `State.*` types are not visible through the default alias. */\nexport default State;\nexport { Context } from './context';\nexport { Component } from './component';\nexport { pending } from './dispatch';\nexport { Caught } from './caught';\n"],"mappings":";;;;;;;;;;;;;;AAYA,kBAAe"}
|
package/dist/observable.js
CHANGED
|
@@ -20,16 +20,18 @@ function observer(state, create) {
|
|
|
20
20
|
}
|
|
21
21
|
return o;
|
|
22
22
|
}
|
|
23
|
-
function observe(object, callback, required) {
|
|
23
|
+
function observe(object, callback, required, cleanup = []) {
|
|
24
24
|
const watching = /* @__PURE__ */ new Set();
|
|
25
25
|
const observing = {
|
|
26
26
|
callback,
|
|
27
27
|
watching,
|
|
28
|
-
required
|
|
28
|
+
required,
|
|
29
|
+
release: cleanup
|
|
29
30
|
};
|
|
30
31
|
const release = listener(object, (key) => {
|
|
31
32
|
if (watching.has(key)) return observing.callback();
|
|
32
33
|
});
|
|
34
|
+
cleanup.push(release);
|
|
33
35
|
if (EffectContext) EffectContext.add((update) => {
|
|
34
36
|
if (update !== true) release();
|
|
35
37
|
});
|
|
@@ -45,10 +47,13 @@ function touch(from, key, value) {
|
|
|
45
47
|
if (active) {
|
|
46
48
|
if (value === void 0 && arguments.length === 3 && active.required) throw new Error(`${Object.getPrototypeOf(from)}.${String(key)} is required in this context.`);
|
|
47
49
|
active.watching.add(key);
|
|
48
|
-
if (value instanceof Object && observer(value)) return observe(value, () => active.callback(), active.required);
|
|
50
|
+
if (value instanceof Object && observer(value)) return observe(value, () => active.callback(), active.required, active.release);
|
|
49
51
|
}
|
|
50
52
|
return value;
|
|
51
53
|
}
|
|
54
|
+
function unobserve(observing) {
|
|
55
|
+
for (const release of observing.release) release();
|
|
56
|
+
}
|
|
52
57
|
function listener(subject, callback, select) {
|
|
53
58
|
const o = observer(subject, true);
|
|
54
59
|
if (select !== void 0 && !(select instanceof Set)) select = new Set([select]);
|
|
@@ -76,17 +81,17 @@ function event(state, key, silent) {
|
|
|
76
81
|
if (key === null) {
|
|
77
82
|
if (!Object.getOwnPropertyDescriptor(state, Observer)) return;
|
|
78
83
|
state[Observer] = null;
|
|
79
|
-
return emit(o, key);
|
|
84
|
+
return emit(o, key, state);
|
|
80
85
|
}
|
|
81
|
-
if (key === void 0) return emit(o, true);
|
|
86
|
+
if (key === void 0) return emit(o, true, state);
|
|
82
87
|
if (!o.events.size && !silent) enqueue(() => {
|
|
83
|
-
emit(o, false);
|
|
88
|
+
emit(o, false, state);
|
|
84
89
|
o.events = /* @__PURE__ */ new Set();
|
|
85
|
-
});
|
|
90
|
+
}, void 0, state);
|
|
86
91
|
o.events.add(key);
|
|
87
|
-
if (!silent) emit(o, key);
|
|
92
|
+
if (!silent) emit(o, key, state);
|
|
88
93
|
}
|
|
89
|
-
function emit(o, key) {
|
|
94
|
+
function emit(o, key, subject) {
|
|
90
95
|
const { listeners, pending, ready } = o;
|
|
91
96
|
if (key === ready) return;
|
|
92
97
|
if (pending.size) {
|
|
@@ -98,7 +103,7 @@ function emit(o, key) {
|
|
|
98
103
|
for (const k of pending) for (const [callback, filter] of listeners) if (!filter || filter.has(k)) {
|
|
99
104
|
const after = callback(k);
|
|
100
105
|
if (after === null) listeners.delete(callback);
|
|
101
|
-
else if (after) enqueue(after);
|
|
106
|
+
else if (typeof after == "function") enqueue(after, void 0, subject);
|
|
102
107
|
}
|
|
103
108
|
if (key === null) listeners.clear();
|
|
104
109
|
else if (key === true) o.ready = true;
|
|
@@ -110,6 +115,7 @@ function watch(target, callback, argument, transition) {
|
|
|
110
115
|
let unset;
|
|
111
116
|
let reset;
|
|
112
117
|
let previous;
|
|
118
|
+
let latest;
|
|
113
119
|
let queued = false;
|
|
114
120
|
let suspense;
|
|
115
121
|
function resume() {
|
|
@@ -124,25 +130,30 @@ function watch(target, callback, argument, transition) {
|
|
|
124
130
|
events = [...o.events];
|
|
125
131
|
if (reset === null) return null;
|
|
126
132
|
if (ignore) {
|
|
127
|
-
if (queued) enqueue(invoke, transition);
|
|
133
|
+
if (queued) enqueue(invoke, transition, target);
|
|
128
134
|
return;
|
|
129
135
|
}
|
|
130
136
|
ignore = true;
|
|
131
137
|
queued = true;
|
|
132
138
|
unset(true);
|
|
133
139
|
unset = void 0;
|
|
134
|
-
enqueue(invoke, transition);
|
|
140
|
+
enqueue(invoke, transition, target);
|
|
135
141
|
}
|
|
136
142
|
function run(release) {
|
|
143
|
+
if (previous !== latest) unobserve(latest);
|
|
137
144
|
const proxy = observe(target, onUpdate, argument === true);
|
|
145
|
+
const current = latest = proxy[Observing];
|
|
138
146
|
const output = callback.call(proxy, proxy, events);
|
|
139
147
|
if (observer(target) === null) {
|
|
140
148
|
if (typeof output == "function") output(null);
|
|
141
149
|
if (release) release(null);
|
|
142
150
|
return;
|
|
143
151
|
}
|
|
144
|
-
if (previous && argument === false && !
|
|
145
|
-
else
|
|
152
|
+
if (previous && argument === false && !current.watching.size) previous.callback = onUpdate;
|
|
153
|
+
else {
|
|
154
|
+
if (previous) unobserve(previous);
|
|
155
|
+
previous = current;
|
|
156
|
+
}
|
|
146
157
|
ignore = false;
|
|
147
158
|
reset = output === null ? null : invoke;
|
|
148
159
|
unset = (key) => {
|
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}\n\nconst Observer: unique symbol = Symbol('Observer');\nconst Observing: unique symbol = Symbol('Observing');\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): T {\n const watching = new Set<Observer.Signal>();\n const observing: Observing = { callback, watching, required };\n\n const release = listener(object, (key) => {\n if (watching.has(key)) return observing.callback();\n });\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(value, () => active.callback(), active.required);\n }\n\n return value;\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);\n }\n\n if (key === undefined) return emit(o, true);\n\n if (!o.events.size && !silent)\n enqueue(() => {\n emit(o, false);\n o.events = new Set();\n });\n\n o.events.add(key);\n\n if (!silent) emit(o, key);\n}\n\nfunction emit(o: Observer, key: Observer.Signal): 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 (after) enqueue(after);\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: T | 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);\n return;\n }\n\n ignore = true;\n queued = true;\n\n unset!(true);\n unset = undefined;\n\n enqueue(invoke, transition);\n }\n\n function run(release?: (update?: boolean | null) => void) {\n const proxy = observe(target, onUpdate, argument === true);\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 && !(proxy as Observed)[Observing]!.watching.size)\n (previous as Observed)[Observing]!.callback = onUpdate;\n else\n previous = proxy;\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 } 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\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)) 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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"}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from "./context.js";
|
|
2
2
|
import { event } from "./observable.js";
|
|
3
|
+
import { Caught } from "./caught.js";
|
|
3
4
|
|
|
4
5
|
//#region src/state.d.ts
|
|
5
6
|
/** Internal state assigned to states. */
|
|
@@ -52,6 +53,14 @@ declare namespace State {
|
|
|
52
53
|
* observed and constructor args applied. May return a cleanup function.
|
|
53
54
|
*/
|
|
54
55
|
after?(this: T, self: T): void | (() => void);
|
|
56
|
+
/**
|
|
57
|
+
* Receives a `Caught` mvc reports for this State or a subclass - most-derived
|
|
58
|
+
* class first, last registered first. Return it (or a replacement) to pass it
|
|
59
|
+
* on; return nothing to handle it; throw to let it escape uncaught. Passed off
|
|
60
|
+
* the end, a warning logs and anything else is thrown - to the writer for a
|
|
61
|
+
* destroyed write, else uncaught.
|
|
62
|
+
*/
|
|
63
|
+
catch?(this: T, error: Caught): Caught | void;
|
|
55
64
|
}
|
|
56
65
|
/** Object overlay to override values and methods on a state. */
|
|
57
66
|
type Assign<T> = Record<string, unknown> & { [K in Field<T>]?: T[K] extends ((...args: infer A) => infer R) ? (this: T, ...args: A) => R : T[K] };
|
|
@@ -208,7 +217,7 @@ declare abstract class State {
|
|
|
208
217
|
* Properties which are not managed by this state will be ignored.
|
|
209
218
|
*
|
|
210
219
|
* @param assign - Object with properties to update.
|
|
211
|
-
* @param silent - If true, listeners will not be notified. If state is destroyed,
|
|
220
|
+
* @param silent - If true, listeners will not be notified. If state is destroyed, drops the update without reporting it.
|
|
212
221
|
* @returns Array of keys updated, syncronously contains keys updated immediately and may be resolved (to itself) when all updates are settled.
|
|
213
222
|
*/
|
|
214
223
|
set(assign?: State.Assign<this>, silent?: boolean): State.Updated<this>;
|
|
@@ -332,9 +341,11 @@ declare function access(state: State, property: string, required?: boolean): any
|
|
|
332
341
|
*
|
|
333
342
|
* This is used internally to update properties, but can also be used to update properties which are not managed by state, or to update values without triggering setters.
|
|
334
343
|
*
|
|
335
|
-
*
|
|
344
|
+
* A destroyed state reports the write - thrown to the writer unless a `catch` handler takes it - and returns `false`; `silent` skips both, and dispatch.
|
|
336
345
|
*/
|
|
337
346
|
declare function update<T>(state: State, key: State.Event<T>, value: T, silent?: boolean, own?: boolean): boolean;
|
|
347
|
+
/** Error thrown by a handler replaying in dispatch, attributed to the State which queued it. */
|
|
348
|
+
declare function fault(err: unknown, owner?: object): void;
|
|
338
349
|
/** Random alphanumberic of length 6; always starts with a letter. */
|
|
339
350
|
declare function uid(): string;
|
|
340
351
|
declare function unbind<T extends Function>(fn: T): T;
|
|
@@ -348,5 +359,5 @@ declare function unbind<T extends Function>(fn?: T): T | undefined;
|
|
|
348
359
|
declare function parent(child: object): State | null | undefined;
|
|
349
360
|
declare function parent(child: object, value: State | null): boolean;
|
|
350
361
|
//#endregion
|
|
351
|
-
export { PENDING, STORE, State, access, apply, children, compute, event, parent, uid, unbind, update };
|
|
362
|
+
export { PENDING, STORE, State, access, apply, children, compute, event, fault, parent, uid, unbind, update };
|
|
352
363
|
//# sourceMappingURL=state.d.ts.map
|