@expressive/mvc 0.90.0 → 0.92.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.
@@ -1 +1 @@
1
- {"version":3,"file":"get.js","names":[],"sources":["../../src/field/get.ts"],"sourcesContent":["import { capture, listener, observer } from '../observable';\nimport { Context } from '../context';\nimport { Model, children, owned, parent, STORE, update } from '../state';\nimport { def } from './def';\n\ndeclare namespace get {\n type Callback<T = any> = (\n state: T,\n subject: Model\n ) => void | boolean | (() => void);\n}\n\n/**\n * Fetches upstream Model from context with optional lifecycle callback.\n * Callback runs on mount and can return cleanup function for unmount.\n *\n * @param Type - Type of Model to fetch.\n * @param callback - Optional lifecycle callback, receives (state, subject). Can return cleanup function.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n callback?: get.Callback<T>\n): T;\n\n/**\n * Fetches and assigns the controller which spawned this host.\n * When parent assigns an instance via `use()` directive, it\n * will be made available to child upon this request.\n *\n * @param Type - Type of controller compatible with this class.\n * @param required - If false, property may be undefined. Otherwise will throw.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n required: false\n): T | undefined;\n\n/**\n * Collects downstream Models, accumulating all instances of specified type\n * for which this is an ancestor. Returns an array that updates as Models\n * are added or removed. Callback runs on each registration and can return\n * cleanup or false to prevent registration.\n *\n * @param Type - Type of Model to collect.\n * @param downstream - Must be true to enable downstream mode.\n * @param callback - Optional lifecycle callback, receives (state, subject). May return false to prevent registration.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n downstream: true,\n callback?: get.Callback<T>\n): T[];\n\n/**\n * Fetches a single downstream Model of specified type.\n * Updates when a matching child appears or is removed.\n * Throws if not found.\n *\n * @param Type - Type of Model to fetch.\n * @param downstream - Must be true to enable downstream mode.\n * @param required - Throw if no match found.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n downstream: true,\n single: true\n): T;\n\n/**\n * Fetches a single downstream Model of specified type.\n * Updates when a matching child appears or is removed.\n * Returns undefined if not found.\n *\n * @param Type - Type of Model to fetch.\n * @param downstream - Must be true to enable downstream mode.\n * @param required - If false, returns undefined if no match found.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n downstream: true,\n required: false\n): T | undefined;\n\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n arg1?: get.Callback<T> | boolean,\n arg2?: get.Callback<T> | boolean\n) {\n return arg1 === true ? below(Type, arg2) : above(Type, arg1);\n}\n\nfunction above<T extends Model>(\n Type: Model.Extends<T>,\n argument: get.Callback<T> | boolean | undefined\n) {\n return def<T>((key, subject) => {\n const hasParent = parent(subject);\n const callback =\n typeof argument === 'function'\n ? (argument as get.Callback<T>)\n : undefined;\n\n function assign(value: T) {\n if (STORE.get(subject)![key] === value) return;\n\n if (callback) {\n const result = callback(value, subject);\n if (typeof result === 'function') subject.set(null, result);\n }\n update(subject, key, value);\n }\n\n if (hasParent && hasParent instanceof Type) {\n assign(hasParent as T);\n return {};\n }\n\n if (Type === Model) {\n if (argument === false) return { get: false, enumerable: false };\n throw new Error(`${subject} has no owner.`);\n }\n\n let found = false;\n let depth = Infinity;\n let level = 0;\n\n for (let p: Model | null | undefined = hasParent; p; p = parent(p), level++) {\n const at = level;\n\n if (p instanceof Type) {\n if (!found) {\n found = true;\n depth = at;\n assign(p as T);\n }\n break;\n }\n\n const remove = children(p, (child) => {\n if (child !== subject && child instanceof Type && at <= depth) {\n found = true;\n depth = at;\n assign(child as T);\n }\n });\n\n subject.set(null, () => { remove(); });\n }\n\n if (!found) {\n const remove = Context.get(subject).get(Type, (state) => {\n if (depth !== Infinity) return;\n found = true;\n assign(state);\n }, false, subject) as () => void;\n\n subject.set(null, () => { remove(); });\n }\n\n if (!found && argument !== false) {\n const missing = () =>\n new Error(`Required ${Type} not found in context for ${subject}.`);\n\n let activating: Model | undefined;\n\n for (\n let p: Model | null | undefined = hasParent;\n p && !observer(p)!.ready;\n p = parent(p)\n )\n activating = p;\n\n if (!activating) throw missing();\n\n listener(activating, () => {\n if (!found) throw missing();\n return null;\n }, true);\n }\n\n return {\n get: argument !== false,\n enumerable: false\n };\n });\n}\n\nfunction below<T extends Model>(\n Type: Model.Extends<T>,\n arg: get.Callback<T> | boolean | undefined\n) {\n return def<T[]>((key, subject) => {\n const context = Context.get(subject);\n const watch = (callback: (state: T) => (() => void) | void) =>\n Type === Model\n ? owned(subject, callback as (state: Model) => (() => void) | void)\n : context.get(Type, callback, true);\n\n if (typeof arg == 'boolean') {\n watch(\n (state) => {\n update(subject, key, state);\n return state.set(null, () => {\n update(subject, key, undefined);\n });\n }\n );\n\n return {\n get: arg,\n value: undefined,\n enumerable: false\n };\n }\n\n const applied = new Set<Model>();\n\n watch(\n (state) => {\n let remove: (() => void) | undefined;\n let release: (() => void) | undefined;\n\n if (applied.has(state)) return;\n\n if (arg) {\n let rejected = false;\n\n capture((fn) => {\n const done = arg(state, subject);\n\n if (done === false) rejected = true;\n else if (typeof done == 'function') remove = done;\n\n release = fn;\n });\n\n if (rejected) return;\n }\n\n applied.add(state);\n update(subject, key, [...applied]);\n\n function done() {\n if (release) release();\n ignore();\n\n applied.delete(state);\n update(subject, key, [...applied]);\n\n if (typeof remove == 'function') remove();\n }\n\n const ignore = state.set(null, done);\n\n return done;\n }\n );\n\n return {\n value: [],\n enumerable: false\n };\n });\n}\n\nexport { get };\n"],"mappings":"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"}
1
+ {"version":3,"file":"get.js","names":[],"sources":["../../src/field/get.ts"],"sourcesContent":["import { capture, listener, observer, watch } from '../observable';\nimport { Context, within } from '../context';\nimport { Model, children, owned, parent, STORE, update } from '../state';\nimport type { Got, Keyed } from '../state';\nimport { def } from './def';\n\ndeclare namespace get {\n type Callback<T = any> = (\n state: T,\n subject: Model\n ) => void | boolean | (() => void);\n}\n\n/**\n * Fetches upstream Model from context with optional lifecycle callback.\n * Callback runs on mount and can return cleanup function for unmount.\n *\n * @param Type - Type of Model to fetch.\n * @param callback - Optional lifecycle callback, receives (state, subject). Can return cleanup function.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n callback?: get.Callback<T>\n): T;\n\n/**\n * Fetches and assigns the controller which spawned this host.\n *\n * @param Type - Type of controller compatible with this class.\n * @param required - If false, property may be undefined. Otherwise will throw.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n required: false\n): T | undefined;\n\n/**\n * Collects downstream Models, accumulating all instances of specified type\n * for which this is an ancestor. Returns an array that updates as Models\n * are added or removed. Callback runs on each registration and can return\n * cleanup or false to prevent registration.\n *\n * @param Type - Type of Model to collect.\n * @param downstream - Must be true to enable downstream mode.\n * @param callback - Optional lifecycle callback, receives (state, subject). May return false to prevent registration.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n downstream: true,\n callback?: get.Callback<T>\n): T[];\n\n/**\n * Fetches a single downstream Model of specified type.\n * Updates when a matching child appears or is removed.\n * Throws if not found.\n *\n * @param Type - Type of Model to fetch.\n * @param downstream - Must be true to enable downstream mode.\n * @param required - Throw if no match found.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n downstream: true,\n single: true\n): T;\n\n/**\n * Fetches a single downstream Model of specified type.\n * Updates when a matching child appears or is removed.\n * Returns undefined if not found.\n *\n * @param Type - Type of Model to fetch.\n * @param downstream - Must be true to enable downstream mode.\n * @param required - If false, returns undefined if no match found.\n */\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n downstream: true,\n required: false\n): T | undefined;\n\n/**\n * Fetches through `Type.get(...args)` as this field is defined, with this\n * Model as origin. Resolves once; a thrown Promise suspends the field and\n * retries once settled. Applies where the first argument is neither boolean\n * nor function - a key for a class overriding static `get`.\n *\n * @param Type - Class to fetch from.\n * @param args - Arguments for `Type.get`.\n */\nfunction get<C extends Model.Extends>(\n Type: C,\n ...args: Keyed<C>\n): Got<C>;\n\nfunction get<T extends Model>(\n Type: Model.Extends<T>,\n arg1?: any,\n ...args: any[]\n): any {\n if (arg1 === true) return below(Type, args[0]);\n\n if (arg1 === undefined || typeof arg1 == 'boolean' || typeof arg1 == 'function')\n return above(Type, arg1);\n\n return def((key, subject) => {\n const resolve = () => update(subject, key, within(subject, () => (Type.get as Function)(arg1, ...args)));\n\n try {\n resolve();\n } catch (error) {\n if (!(error instanceof Promise)) throw error;\n\n watch(subject, () => {\n resolve();\n return null;\n });\n }\n\n return {\n get: true,\n enumerable: false\n };\n });\n}\n\nfunction above<T extends Model>(\n Type: Model.Extends<T>,\n argument: get.Callback<T> | boolean | undefined\n) {\n return def<T>((key, subject) => {\n const hasParent = parent(subject);\n const callback =\n typeof argument === 'function'\n ? (argument as get.Callback<T>)\n : undefined;\n\n function assign(value: T) {\n if (STORE.get(subject)![key] === value) return;\n\n if (callback) {\n const result = callback(value, subject);\n if (typeof result === 'function') subject.set(null, result);\n }\n update(subject, key, value);\n }\n\n if (hasParent && hasParent instanceof Type) {\n assign(hasParent as T);\n return {};\n }\n\n if (Type === Model) {\n if (argument === false) return { get: false, enumerable: false };\n throw new Error(`${subject} has no owner.`);\n }\n\n let found = false;\n let depth = Infinity;\n let level = 0;\n\n for (let p: Model | null | undefined = hasParent; p; p = parent(p), level++) {\n const at = level;\n\n if (p instanceof Type) {\n if (!found) {\n found = true;\n depth = at;\n assign(p as T);\n }\n break;\n }\n\n const remove = children(p, (child) => {\n if (child !== subject && child instanceof Type && at <= depth) {\n found = true;\n depth = at;\n assign(child as T);\n }\n });\n\n subject.set(null, () => { remove(); });\n }\n\n if (!found) {\n const remove = Context.get(subject).get(Type, (state) => {\n if (depth !== Infinity) return;\n found = true;\n assign(state);\n }, false, subject) as () => void;\n\n subject.set(null, () => { remove(); });\n }\n\n if (!found && argument !== false) {\n const missing = () =>\n new Error(`Required ${Type} not found in context for ${subject}.`);\n\n let activating: Model | undefined;\n\n for (\n let p: Model | null | undefined = hasParent;\n p && !observer(p)!.ready;\n p = parent(p)\n )\n activating = p;\n\n if (!activating) throw missing();\n\n listener(activating, () => {\n if (!found) throw missing();\n return null;\n }, true);\n }\n\n return {\n get: argument !== false,\n enumerable: false\n };\n });\n}\n\nfunction below<T extends Model>(\n Type: Model.Extends<T>,\n arg: get.Callback<T> | boolean | undefined\n) {\n return def<T[]>((key, subject) => {\n const context = Context.get(subject);\n const watch = (callback: (state: T) => (() => void) | void) =>\n Type === Model\n ? owned(subject, callback as (state: Model) => (() => void) | void)\n : context.get(Type, callback, true);\n\n if (typeof arg == 'boolean') {\n watch(\n (state) => {\n update(subject, key, state);\n return state.set(null, () => {\n update(subject, key, undefined);\n });\n }\n );\n\n return {\n get: arg,\n value: undefined,\n enumerable: false\n };\n }\n\n const applied = new Set<Model>();\n\n watch(\n (state) => {\n let remove: (() => void) | undefined;\n let release: (() => void) | undefined;\n\n if (applied.has(state)) return;\n\n if (arg) {\n let rejected = false;\n\n capture((fn) => {\n const done = arg(state, subject);\n\n if (done === false) rejected = true;\n else if (typeof done == 'function') remove = done;\n\n release = fn;\n });\n\n if (rejected) return;\n }\n\n applied.add(state);\n update(subject, key, [...applied]);\n\n function done() {\n if (release) release();\n ignore();\n\n applied.delete(state);\n update(subject, key, [...applied]);\n\n if (typeof remove == 'function') remove();\n }\n\n const ignore = state.set(null, done);\n\n return done;\n }\n );\n\n return {\n value: [],\n enumerable: false\n };\n });\n}\n\nexport { get };\n"],"mappings":"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"}
@@ -12,6 +12,10 @@ declare function has<T extends Model, K extends Model.Field<T>>(Type: new (...ar
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);
15
+ /** The instance to render - this, or the source behind a derived view. */
16
+ get is(): this;
17
+ /** Members to render, as a host sees them. */
18
+ render(): T[];
15
19
  get size(): number;
16
20
  get(): Model.Export<T>[];
17
21
  get(index: number): T | undefined;
@@ -41,6 +45,10 @@ interface From<T extends Model, K extends Model.Field<T>> extends Pool<T, [from:
41
45
  }
42
46
  declare class Pool<T, A extends unknown[] = unknown[], R = T> {
43
47
  constructor(make: Function, fromKey?: string);
48
+ /** The instance to render - this, or the source behind a derived view. */
49
+ get is(): this;
50
+ /** Members to render, as a host sees them. */
51
+ render(): T[];
44
52
  get size(): number;
45
53
  add(...args: A): R;
46
54
  get(): Model.Export<T>[];
package/dist/field/has.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { event, listener, touch } from "../observable.js";
2
2
  import { Model, parent } from "../state.js";
3
- import { Context } from "../context.js";
3
+ import { join } from "../context.js";
4
+ import { element } from "../element.js";
4
5
  import { def } from "./def.js";
5
6
 
6
7
  //#region src/field/has.ts
@@ -27,6 +28,14 @@ var List = class {
27
28
  OWNED.set(this, /* @__PURE__ */ new Map());
28
29
  event(this);
29
30
  }
31
+ /** The instance to render - this, or the source behind a derived view. */
32
+ get is() {
33
+ return source(this);
34
+ }
35
+ /** Members to render, as a host sees them. */
36
+ render() {
37
+ return [...this];
38
+ }
30
39
  get size() {
31
40
  return touch(this, LENGTH, items(this).length);
32
41
  }
@@ -108,6 +117,14 @@ var Pool = class {
108
117
  OWNED.set(this, /* @__PURE__ */ new Map());
109
118
  event(this);
110
119
  }
120
+ /** The instance to render - this, or the source behind a derived view. */
121
+ get is() {
122
+ return source(this);
123
+ }
124
+ /** Members to render, as a host sees them. */
125
+ render() {
126
+ return [...this];
127
+ }
111
128
  get size() {
112
129
  return touch(this, SHAPE, members(this).size);
113
130
  }
@@ -177,7 +194,7 @@ function adopt(target, key, value) {
177
194
  const fresh = parent(value, owner ?? null);
178
195
  const evict = listener(value, () => void target.delete(key), null);
179
196
  let detach;
180
- if (fresh && owner) detach = Context.get(owner).add(value);
197
+ if (fresh && owner) detach = join(owner, value);
181
198
  OWNED.get(target).set(key, () => {
182
199
  evict();
183
200
  if (detach) detach();
@@ -231,6 +248,8 @@ Object.assign(has, {
231
248
  List,
232
249
  Pool
233
250
  });
251
+ element(List);
252
+ element(Pool);
234
253
 
235
254
  //#endregion
236
255
  export { has };
@@ -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 { Model, 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 Model>(\n Type: new (...args: Model.Args<T>) => T\n): Create<T>;\n\nfunction has<T extends Model, K extends Model.Field<T>>(\n Type: new (...args: Model.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(): Model.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 Model> extends Pool<T, Model.Args<T>> {\n add(...args: Model.Args<T>): T;\n add(instance: T): T;\n}\n\ninterface From<T extends Model, K extends Model.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 (Model.is(make)) {\n const Type = make as unknown as Model.Type;\n\n make = (...args: Model.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(): Model.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 Model)) 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":";;;;;;AAKA,MAAM,SAAS,OAAO,SAAS;AAC/B,MAAM,QAAQ,OAAO,QAAQ;AAE7B,MAAM,wBAAQ,IAAI,SAA4B;AAC9C,MAAM,0BAAU,IAAI,SAA+B;AACnD,MAAM,wBAAQ,IAAI,SAA2C;AAC7D,MAAM,uBAAO,IAAI,SAAuB;AAyBxC,SAAS,IACP,KACA,SACS;AACT,QAAO,KAAK,MAAM,YAAY;EAC5B,MAAM,QACJ,OAAO,OAAO,aAAa,IAAI,KAAK,KAAK,QAAQ,GAAG,IAAI,KAAK,IAAI;AAEnE,SAAO,OAAO,QAAQ;AACtB,WAAS,eAAe,MAAM,OAAO,EAAE,KAAK;AAE5C,SAAO;GAAE,KAAK;GAAO;GAAO;GAC5B;;AAGJ,IAAM,OAAN,MAAc;CACZ,YAAY,SAAsC;AAChD,QAAM,IAAI,MAAM,UAAU,MAAM,KAAK,QAAQ,GAAG,EAAE,CAAC;AACnD,QAAM,IAAI,sBAAM,IAAI,KAAK,CAAC;AAE1B,QAAM,KAAK;;CAGb,IAAI,OAAe;AACjB,SAAO,MAAM,MAAM,QAAQ,MAAS,KAAK,CAAC,OAAO;;CAOnD,IAAI,KAA6B,QAAsB;EACrD,MAAM,SAAS,MAAS,KAAK;AAE7B,MAAI,QAAQ,OAAW,QAAO,OAAO,IAAI,YAAY;AAErD,MAAI,OAAO,QAAQ,WAAY,QAAO,OAAO,MAAM,IAAI;AAEvD,MAAI,OAAO,WAAW,UAAU;GAC9B,MAAM,KAAK,MAAM,IAAI,OAAO,SAAS,MAAM;AAE3C,UAAO,KAAK,KAAK,MAAM,OAAO,SAC1B,MAAM,MAAM,OAAO,GACnB,MAAM,MAAM,IAAI,OAAO,IAAI;;AAGjC,QAAM,MAAM,OAAO;EAEnB,MAAM,QAAQ,MAAM,IAAI,KAAK,IAAI,OAAO,SAAS,KAAK,EAAE,GAAG;AAE3D,SAAO,OACJ,MAAM,OAAO,KAAK,IAAI,QAAQ,OAAO,OAAO,CAAC,CAC7C,KAAK,GAAG,MAAM,MAAM,MAAM,QAAQ,GAAG,EAAE,CAAC;;CAG7C,IAAI,OAAe,OAAU;EAC3B,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,SAAS,MAAM,IAAI,OAAO;EAChC,MAAM,KAAK,QAAQ,IAAI,OAAO,SAAS,QAAQ;AAE/C,MAAI,KAAK,KAAK,MAAM,OAAO,UAAU,OAAO,QAAQ,MAAO;AAE3D,SAAO,MAAM;AACb,QAAM,QAAQ,GAAG;;CAGnB,IAAI,OAAe,GAAG,QAAa;AACjC,MAAI,CAAC,OAAO,OAAQ;EAEpB,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,MAAM,MAAM,IAAI,OAAO;EAC7B,MAAM,KACJ,QAAQ,IACJ,KAAK,IAAI,IAAI,SAAS,OAAO,EAAE,GAC/B,KAAK,IAAI,OAAO,IAAI,OAAO;AAEjC,MAAI,OAAO,IAAI,GAAG,GAAG,OAAO;AAE5B,OAAK,IAAI,IAAI,IAAI,IAAI,IAAI,QAAQ,IAAK,OAAM,QAAQ,EAAE;AACtD,QAAM,QAAQ,OAAO;;CAGvB,KAAK,GAAG,QAAqB;AAC3B,OAAK,IAAI,MAAM,KAAK,CAAC,QAAQ,GAAG,OAAO;AACvC,SAAO,MAAM,KAAK,CAAC;;CAMrB,IAAI,QAAQ,IAAI,OAAqC;EACnD,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,SAAS,MAAM,IAAI,OAAO;EAChC,MAAM,SAAS,OAAO;EACtB,MAAM,QACJ,QAAQ,IAAI,KAAK,IAAI,SAAS,OAAO,EAAE,GAAG,KAAK,IAAI,OAAO,OAAO;EACnE,MAAM,UAAU,OAAO,OAAO,OAAO,SAAS,EAAE;AAEhD,MAAI,QAAQ,QAAQ;GAClB,MAAM,MAAM,KAAK,IAAI,QAAQ,OAAO,OAAO;AAC3C,QAAK,IAAI,IAAI,OAAO,IAAI,KAAK,IAAK,OAAM,QAAQ,EAAE;AAClD,SAAM,QAAQ,OAAO;;AAGvB,SAAO,UAAU,SAAY,QAAQ,KAAK;;CAG5C,QAAQ;AACN,OAAK,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO;;CAGjC,EAAE,OAAO,YAAiC;EACxC,MAAM,SAAS,MAAS,KAAK;AAE7B,QAAM,MAAM,OAAO;AAEnB,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,OAAM,MAAM,MAAM,GAAG,OAAO,GAAG;;CAKzE,IAAO,IAAkB,QAAiB;AACxC,SAAO,MAAM,MAAM,IAAI,UAAU,SAAS,GAAG,OAAO;;CAGtD,OAAO,IAAuB;AAC5B,SAAO,SAAS,MAAM,GAAG;;CAG3B,IAAI,IAA2B;AAC7B,SAAO,MAAM,MAAM,GAAG;;CAGxB,IAAI,IAA2B;AAC7B,SAAO,CAAC,MAAM,OAAO,GAAG,GAAG,SAAS,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC;;;AAexD,IAAM,OAAN,MAAsD;CACpD,YAAY,MAAgB,SAAkB;AAC5C,MAAI,MAAM,GAAG,KAAK,EAAE;GAClB,MAAM,OAAO;AAEb,WAAQ,GAAG,SACT,KAAK,UAAU,KAAK,KAAK,cAAc,OAAO,KAAK,KACnD,UAAU,IAAI,KAAK,GAAG,UAAU,KAAK,IAAI,CAAC,GAC1C,IAAI,KAAK,GAAG,KAAK;;AAGrB,UAAQ,IAAI,sBAAM,IAAI,KAAK,CAAC;AAC5B,OAAK,IAAI,MAAM,KAAa;AAC5B,QAAM,IAAI,sBAAM,IAAI,KAAK,CAAC;AAE1B,QAAM,KAAK;;CAGb,IAAI,OAAe;AACjB,SAAO,MAAM,MAAM,OAAO,QAAW,KAAK,CAAC,KAAK;;CAGlD,IAAI,GAAG,MAAY;EACjB,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,OAAO,KAAK,IAAI,OAAO,CAAE,GAAG,KAAK;AAEvC,MAAI,QAAQ,KAAM,QAAO;EAEzB,MAAM,SAAS,QAAQ,IAAI,OAAO;AAElC,MAAI,CAAC,OAAO,IAAI,KAAK,EAAE;AACrB,UAAO,IAAI,KAAK;AAChB,SAAM,QAAQ,MAAM,KAAK;AACzB,SAAM,QAAQ,KAAc;AAC5B,SAAM,QAAQ,MAAM;;AAGtB,SAAO;;CAKT,IAAI,WAA+B;AACjC,SAAO,YACH,OAAO,MAAM,UAAU,GACvB,MAAM,KAAK,QAAW,KAAK,EAAE,YAAY;;CAG/C,IAAI,OAAmB;AACrB,SAAO,MAAM,MAAM,OAAO,QAAW,KAAK,CAAC,IAAI,MAAM,CAAC;;CAGxD,OAAO,OAAmB;EACxB,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,SAAS,QAAQ,IAAI,OAAO;AAElC,MAAI,CAAC,OAAO,IAAI,MAAM,CAAE,QAAO;AAE/B,UAAQ,QAAQ,MAAM;AACtB,SAAO,OAAO,MAAM;AAEpB,QAAM,QAAQ,MAAe;AAC7B,QAAM,QAAQ,MAAM;AAEpB,SAAO;;CAGT,QAAQ;EACN,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,SAAS,QAAQ,IAAI,OAAO;AAElC,MAAI,CAAC,OAAO,KAAM;EAElB,MAAM,UAAU,MAAM,KAAK,OAAO;AAElC,OAAK,MAAM,SAAS,QAAS,SAAQ,QAAQ,MAAM;AAEnD,SAAO,OAAO;AAEd,OAAK,MAAM,SAAS,QAAS,OAAM,QAAQ,MAAe;AAC1D,QAAM,QAAQ,MAAM;;CAGtB,EAAE,OAAO,YAAiC;EACxC,MAAM,SAAS,QAAW,KAAK;AAE/B,QAAM,MAAM,MAAM;AAElB,OAAK,MAAM,SAAS,OAAQ,OAAM,MAAM,MAAM,OAAO,MAAM;;CAK7D,IAAO,IAAkB,QAAiB;AACxC,SAAO,MAAM,MAAM,IAAI,UAAU,SAAS,GAAG,OAAO;;CAGtD,OAAO,IAAuB;AAC5B,SAAO,SAAS,MAAM,GAAG;;CAG3B,IAAI,IAA2B;AAC7B,SAAO,MAAM,MAAM,GAAG;;CAGxB,IAAI,IAA2B;AAC7B,SAAO,CAAC,MAAM,OAAO,GAAG,GAAG,SAAS,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC;;;AAIxD,SAAS,OAAyB,MAAY;AAC5C,QAAO,MAAM,IAAI,KAAK,GAAG,OAAO,OAAO,eAAe,KAAK;;AAG7D,SAAS,MACP,QACA,KACA,OACA;AACA,KAAI,EAAE,iBAAiB,OAAQ;CAE/B,MAAM,QAAQ,OAAO,OAAiB;CACtC,MAAM,QAAQ,OAAO,OAAO,SAAS,KAAK;CAC1C,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO,OAAO,IAAa,EAAE,KAAK;CAE3E,IAAI;AAEJ,KAAI,SAAS,MACX,UAAS,QAAQ,IAAI,MAAM,CAAC,IAAI,MAAM;AAExC,OAAM,IAAI,OAAO,CAAE,IAAI,WAAW;AAChC,SAAO;AACP,MAAI,OAAQ,SAAQ;AACpB,MAAI,MAAO,OAAM,IAAI,KAAK;GAC1B;AAEF,KAAI,MAAO,OAAM,MAAM;;AAGzB,SAAS,QAAQ,QAAgB,KAAc;CAC7C,MAAM,QAAQ,MAAM,IAAI,OAAO;CAC/B,MAAM,OAAO,MAAM,IAAI,IAAI;AAE3B,KAAI,MAAM;AACR,QAAM,OAAO,IAAI;AACjB,QAAM;;;AAIV,SAAS,YAAY,OAAY;AAC/B,QAAO,SAAS,OAAO,UAAU,YAAY,OAAO,MAAM,QAAQ,aAC9D,MAAM,KAAK,GACX;;AAGN,SAAS,MAAS,MAAmB;AACnC,QAAO,MAAM,IAAI,OAAO,KAAK,CAAC;;AAGhC,SAAS,QAAW,MAAsB;AACxC,QAAO,QAAQ,IAAI,OAAO,KAAK,CAAC;;AAGlC,SAAS,OACP,MACA,IACe;CACf,IAAI,IAAI;AAER,MAAK,MAAM,SAAS,KAClB,KAAI,GAAG,OAAO,KAAK,KAAK,CAAE,QAAO;;AAGrC,SAAS,MAAS,MAAmB,IAA2B;CAC9D,IAAI,IAAI;AAER,MAAK,MAAM,SAAS,KAClB,KAAI,GAAG,OAAO,KAAK,KAAK,CAAE,QAAO;AAEnC,QAAO;;AAGT,SAAS,MACP,MACA,IACA,MACA,QACK;CACL,MAAM,MAAW,EAAE;CACnB,IAAI,IAAI;AAER,MAAK,MAAM,SAAS,MAAM;EACxB,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK;AACnC,MAAI,QAAQ,WAAW,OAAQ;AAC/B,MAAI,KAAK,OAAO;;AAGlB,QAAO;;AAGT,SAAS,SAAY,MAAmB,IAAuB;CAC7D,MAAM,MAAW,EAAE;CACnB,IAAI,IAAI;AAER,MAAK,MAAM,SAAS,KAAM,KAAI,GAAG,OAAO,KAAK,KAAK,CAAE,KAAI,KAAK,MAAM;AAEnE,QAAO;;AAGT,OAAO,OAAO,KAAK;CAAE;CAAM;CAAM,CAAC"}
1
+ {"version":3,"file":"has.js","names":[],"sources":["../../src/field/has.ts"],"sourcesContent":["import { join } from '../context';\nimport { def } from './def';\nimport { element } from '../element';\nimport { event, listener, touch } from '../observable';\nimport { Model, parent } from '../state';\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 Model>(\n Type: new (...args: Model.Args<T>) => T\n): Create<T>;\n\nfunction has<T extends Model, K extends Model.Field<T>>(\n Type: new (...args: Model.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 /** The instance to render - this, or the source behind a derived view. */\n get is(): this {\n return source(this);\n }\n\n /** Members to render, as a host sees them. */\n render(): T[] {\n return [...this];\n }\n\n get size(): number {\n return touch(this, LENGTH, items<T>(this).length);\n }\n\n get(): Model.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 Model> extends Pool<T, Model.Args<T>> {\n add(...args: Model.Args<T>): T;\n add(instance: T): T;\n}\n\ninterface From<T extends Model, K extends Model.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 (Model.is(make)) {\n const Type = make as unknown as Model.Type;\n\n make = (...args: Model.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 /** The instance to render - this, or the source behind a derived view. */\n get is(): this {\n return source(this);\n }\n\n /** Members to render, as a host sees them. */\n render(): T[] {\n return [...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(): Model.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 Model)) 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 = join(owner, 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\nelement(List);\nelement(Pool);\n\nexport { has };\n"],"mappings":"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"}
@@ -14,6 +14,10 @@ declare function map<K, V>(entries?: Iterable<readonly [K, V]> | false | null):
14
14
  declare function map<A extends [unknown, ...unknown[]], V>(make: (...args: A) => V): map.Create<A, V>;
15
15
  declare class Managed<K, V> extends Map<K, V> {
16
16
  constructor(arg?: Iterable<readonly [K, V]> | Function | false | null);
17
+ /** The instance to render - this, or the source behind a derived view. */
18
+ get is(): this;
19
+ /** Values to render, as a host sees them. */
20
+ render(): V[];
17
21
  get size(): number;
18
22
  get(): ReadonlyMap<K, Model.Export<V>>;
19
23
  get(key: K): V | undefined;
package/dist/field/map.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { event, listener, touch } from "../observable.js";
2
2
  import { Model, parent } from "../state.js";
3
- import { Context } from "../context.js";
3
+ import { join } from "../context.js";
4
+ import { element } from "../element.js";
4
5
  import { def } from "./def.js";
5
6
 
6
7
  //#region src/field/map.ts
@@ -30,6 +31,14 @@ var Managed = class extends Map {
30
31
  event(this);
31
32
  if (arg && typeof arg != "function") for (const [key, value] of arg) store(this, key, value);
32
33
  }
34
+ /** The instance to render - this, or the source behind a derived view. */
35
+ get is() {
36
+ return source(this);
37
+ }
38
+ /** Values to render, as a host sees them. */
39
+ render() {
40
+ return [...this.values()];
41
+ }
33
42
  get size() {
34
43
  return touch(this, SHAPE, MAP_SIZE.call(source(this)));
35
44
  }
@@ -116,7 +125,7 @@ function store(target, key, value) {
116
125
  const fresh = parent(value, owner ?? null);
117
126
  const evict = listener(value, () => void target.delete(key), null);
118
127
  let detach;
119
- if (fresh && owner) detach = Context.get(owner).add(value);
128
+ if (fresh && owner) detach = join(owner, value);
120
129
  OWNED.get(target).set(key, () => {
121
130
  evict();
122
131
  if (detach) detach();
@@ -138,6 +147,7 @@ function release(target, key) {
138
147
  function source(from) {
139
148
  return OWNED.has(from) ? from : Object.getPrototypeOf(from);
140
149
  }
150
+ element(Managed);
141
151
 
142
152
  //#endregion
143
153
  export { map };
@@ -1 +1 @@
1
- {"version":3,"file":"map.js","names":[],"sources":["../../src/field/map.ts"],"sourcesContent":["import { Context } from '../context';\nimport { event, listener, touch } from '../observable';\nimport { Model, parent } from '../state';\nimport { def } from './def';\n\nconst SHAPE = Symbol('shape');\nconst KEYED = (_key: unknown, value: unknown) => value;\n\nconst MAKE = new WeakMap<object, Function>();\nconst OWNED = new WeakMap<object, Map<unknown, () => void>>();\n\nconst MAP = Map.prototype;\nconst MAP_SIZE = Object.getOwnPropertyDescriptor(MAP, 'size')!.get!;\n\ndeclare namespace map {\n export interface Create<A extends [unknown, ...unknown[]], V> extends Managed<A[0], V> {\n set(...args: A): this;\n }\n\n export interface Insert<K, V> extends Managed<K, V> {\n set(key: K, value: V): this;\n }\n\n export { Managed };\n}\n\nfunction map<K, V>(\n entries?: Iterable<readonly [K, V]> | false | null\n): map.Insert<K, V>;\n\nfunction map<A extends [unknown, ...unknown[]], V>(\n make: (...args: A) => V\n): map.Create<A, V>;\n\nfunction map(\n arg?: Iterable<readonly [unknown, unknown]> | Function | false | null\n): unknown {\n return def((_key, subject) => {\n const value = new Managed(typeof arg == 'function' && arg);\n\n parent(value, subject);\n listener(subject, () => value.clear(), null);\n\n if (arg && typeof arg == 'object')\n for (const [key, entry] of arg) value.set(key, entry);\n\n return { set: false, value };\n });\n}\n\nclass Managed<K, V> extends Map<K, V> {\n constructor(arg?: Iterable<readonly [K, V]> | Function | false | null) {\n super();\n\n MAKE.set(this, typeof arg == 'function' ? arg : KEYED);\n OWNED.set(this, new Map());\n\n event(this);\n\n if (arg && typeof arg != 'function')\n for (const [key, value] of arg) store(this, key, value);\n }\n\n get size(): number {\n return touch(this, SHAPE, MAP_SIZE.call(source(this)));\n }\n\n get(): ReadonlyMap<K, Model.Export<V>>;\n get(key: K): V | undefined;\n get(key?: K): unknown {\n const target = source(this);\n\n return arguments.length\n ? touch(this, key, super.get.call(target, key as K)) \n : new Map(\n Array.from(MAP.entries.call(target), ([key, value]) => [\n key,\n value && typeof value === 'object' && typeof value.get === 'function'\n ? value.get()\n : value\n ])\n );\n }\n\n has(key: K): boolean {\n return touch(this, key, MAP.has.call(source(this), key));\n }\n\n set(key: K, ...rest: unknown[]): this {\n const target = source(this);\n const value = MAKE.get(target)!(key, ...rest) as V;\n\n store(target, key, value);\n return this;\n }\n\n delete(key: K) {\n const target = source(this);\n\n if (!MAP.has.call(target, key)) return false;\n\n release(target, key);\n MAP.delete.call(target, key);\n\n event(target, key as never);\n event(target, SHAPE);\n\n return true;\n }\n\n clear() {\n const target = source(this);\n const keys = Array.from(MAP.keys.call(target));\n\n if (!keys.length) return;\n\n for (const key of keys) release(target, key);\n\n MAP.clear.call(target);\n\n for (const key of keys) event(target, key as never);\n event(target, SHAPE);\n }\n\n entries(): MapIterator<[K, V]>;\n entries<R>(fn: (entry: [K, V]) => R): Iterable<R>;\n entries(fn?: (entry: [K, V]) => unknown): any {\n const self = this;\n function* iterate() {\n const target = source(self);\n\n touch(self, SHAPE);\n\n for (const [key, value] of MAP.entries.call(target))\n yield [key, touch(self, key, value)] as [K, V];\n }\n\n return fn ? transform(iterate, fn) : iterate();\n }\n\n keys(): MapIterator<K>;\n keys<R>(fn: (key: K) => R): Iterable<R>;\n keys(fn?: (key: K) => unknown): any {\n const self = this;\n function* iterate() {\n touch(self, SHAPE);\n yield* MAP.keys.call(source(self)) as IterableIterator<K>;\n }\n\n return fn ? transform(iterate, fn) : iterate();\n }\n\n values(): MapIterator<V>;\n values<R>(fn: (value: V, key: K) => R): Iterable<R>;\n values(fn?: (value: V, key: K) => unknown): any {\n if (fn)\n return this.entries(([key, value]) => fn(value, key));\n\n const self = this;\n return (function* () {\n for (const [, value] of self.entries())\n yield value;\n })();\n }\n\n forEach(\n callbackfn: (value: V, key: K, map: this) => void,\n thisArg?: unknown\n ) {\n for (const [key, value] of this.entries())\n callbackfn.call(thisArg, value, key, this);\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n}\n\nObject.assign(map, { Managed });\n\nfunction transform<T, R>(\n iterate: () => Generator<T>,\n fn: (item: T) => R\n): Iterable<R> {\n return {\n *[Symbol.iterator]() {\n for (const item of iterate())\n try {\n yield fn(item);\n } catch (err) {\n if (err !== false) throw err;\n }\n }\n };\n}\n\nfunction store<K, V>(target: Managed<K, V>, key: K, value: V) {\n const exists = MAP.has.call(target, key);\n\n if (exists) {\n if (MAP.get.call(target, key) === value) return;\n\n release(target, key);\n }\n\n MAP.set.call(target, key, value);\n\n if (value instanceof Model) {\n const owner = parent(target);\n const fresh = parent(value, owner ?? null);\n const evict = listener(value, () => void target.delete(key), 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\n event(target, key as never);\n\n if (!exists) event(target, SHAPE);\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 source<T extends object>(from: T): T {\n return OWNED.has(from) ? from : Object.getPrototypeOf(from);\n}\n\nexport { map };\n"],"mappings":"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"}
1
+ {"version":3,"file":"map.js","names":[],"sources":["../../src/field/map.ts"],"sourcesContent":["import { join } from '../context';\nimport { def } from './def';\nimport { element } from '../element';\nimport { event, listener, touch } from '../observable';\nimport { Model, parent } from '../state';\n\nconst SHAPE = Symbol('shape');\nconst KEYED = (_key: unknown, value: unknown) => value;\n\nconst MAKE = new WeakMap<object, Function>();\nconst OWNED = new WeakMap<object, Map<unknown, () => void>>();\n\nconst MAP = Map.prototype;\nconst MAP_SIZE = Object.getOwnPropertyDescriptor(MAP, 'size')!.get!;\n\ndeclare namespace map {\n export interface Create<A extends [unknown, ...unknown[]], V> extends Managed<A[0], V> {\n set(...args: A): this;\n }\n\n export interface Insert<K, V> extends Managed<K, V> {\n set(key: K, value: V): this;\n }\n\n export { Managed };\n}\n\nfunction map<K, V>(\n entries?: Iterable<readonly [K, V]> | false | null\n): map.Insert<K, V>;\n\nfunction map<A extends [unknown, ...unknown[]], V>(\n make: (...args: A) => V\n): map.Create<A, V>;\n\nfunction map(\n arg?: Iterable<readonly [unknown, unknown]> | Function | false | null\n): unknown {\n return def((_key, subject) => {\n const value = new Managed(typeof arg == 'function' && arg);\n\n parent(value, subject);\n listener(subject, () => value.clear(), null);\n\n if (arg && typeof arg == 'object')\n for (const [key, entry] of arg) value.set(key, entry);\n\n return { set: false, value };\n });\n}\n\nclass Managed<K, V> extends Map<K, V> {\n constructor(arg?: Iterable<readonly [K, V]> | Function | false | null) {\n super();\n\n MAKE.set(this, typeof arg == 'function' ? arg : KEYED);\n OWNED.set(this, new Map());\n\n event(this);\n\n if (arg && typeof arg != 'function')\n for (const [key, value] of arg) store(this, key, value);\n }\n\n /** The instance to render - this, or the source behind a derived view. */\n get is(): this {\n return source(this);\n }\n\n /** Values to render, as a host sees them. */\n render(): V[] {\n return [...this.values()];\n }\n\n get size(): number {\n return touch(this, SHAPE, MAP_SIZE.call(source(this)));\n }\n\n get(): ReadonlyMap<K, Model.Export<V>>;\n get(key: K): V | undefined;\n get(key?: K): unknown {\n const target = source(this);\n\n return arguments.length\n ? touch(this, key, super.get.call(target, key as K)) \n : new Map(\n Array.from(MAP.entries.call(target), ([key, value]) => [\n key,\n value && typeof value === 'object' && typeof value.get === 'function'\n ? value.get()\n : value\n ])\n );\n }\n\n has(key: K): boolean {\n return touch(this, key, MAP.has.call(source(this), key));\n }\n\n set(key: K, ...rest: unknown[]): this {\n const target = source(this);\n const value = MAKE.get(target)!(key, ...rest) as V;\n\n store(target, key, value);\n return this;\n }\n\n delete(key: K) {\n const target = source(this);\n\n if (!MAP.has.call(target, key)) return false;\n\n release(target, key);\n MAP.delete.call(target, key);\n\n event(target, key as never);\n event(target, SHAPE);\n\n return true;\n }\n\n clear() {\n const target = source(this);\n const keys = Array.from(MAP.keys.call(target));\n\n if (!keys.length) return;\n\n for (const key of keys) release(target, key);\n\n MAP.clear.call(target);\n\n for (const key of keys) event(target, key as never);\n event(target, SHAPE);\n }\n\n entries(): MapIterator<[K, V]>;\n entries<R>(fn: (entry: [K, V]) => R): Iterable<R>;\n entries(fn?: (entry: [K, V]) => unknown): any {\n const self = this;\n function* iterate() {\n const target = source(self);\n\n touch(self, SHAPE);\n\n for (const [key, value] of MAP.entries.call(target))\n yield [key, touch(self, key, value)] as [K, V];\n }\n\n return fn ? transform(iterate, fn) : iterate();\n }\n\n keys(): MapIterator<K>;\n keys<R>(fn: (key: K) => R): Iterable<R>;\n keys(fn?: (key: K) => unknown): any {\n const self = this;\n function* iterate() {\n touch(self, SHAPE);\n yield* MAP.keys.call(source(self)) as IterableIterator<K>;\n }\n\n return fn ? transform(iterate, fn) : iterate();\n }\n\n values(): MapIterator<V>;\n values<R>(fn: (value: V, key: K) => R): Iterable<R>;\n values(fn?: (value: V, key: K) => unknown): any {\n if (fn)\n return this.entries(([key, value]) => fn(value, key));\n\n const self = this;\n return (function* () {\n for (const [, value] of self.entries())\n yield value;\n })();\n }\n\n forEach(\n callbackfn: (value: V, key: K, map: this) => void,\n thisArg?: unknown\n ) {\n for (const [key, value] of this.entries())\n callbackfn.call(thisArg, value, key, this);\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n}\n\nObject.assign(map, { Managed });\n\nfunction transform<T, R>(\n iterate: () => Generator<T>,\n fn: (item: T) => R\n): Iterable<R> {\n return {\n *[Symbol.iterator]() {\n for (const item of iterate())\n try {\n yield fn(item);\n } catch (err) {\n if (err !== false) throw err;\n }\n }\n };\n}\n\nfunction store<K, V>(target: Managed<K, V>, key: K, value: V) {\n const exists = MAP.has.call(target, key);\n\n if (exists) {\n if (MAP.get.call(target, key) === value) return;\n\n release(target, key);\n }\n\n MAP.set.call(target, key, value);\n\n if (value instanceof Model) {\n const owner = parent(target);\n const fresh = parent(value, owner ?? null);\n const evict = listener(value, () => void target.delete(key), null);\n\n let detach: (() => void) | undefined;\n\n if (fresh && owner)\n detach = join(owner, 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\n event(target, key as never);\n\n if (!exists) event(target, SHAPE);\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 source<T extends object>(from: T): T {\n return OWNED.has(from) ? from : Object.getPrototypeOf(from);\n}\n\nelement(Managed);\n\nexport { map };\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,4 +8,4 @@ import { has } from "./field/has.js";
8
8
  import { map } from "./field/map.js";
9
9
  import { ref } from "./field/ref.js";
10
10
  import { set } from "./field/set.js";
11
- export { Component, Context, Model, Model as State, def, Model as default, get, has, map, pending, ref, set, unbind };
11
+ export { Component, Context, Model, def, Model as default, get, has, map, pending, ref, set, unbind };
package/dist/index.js CHANGED
@@ -14,5 +14,5 @@ import { ref } from "./field/ref.js";
14
14
  var src_default = Model;
15
15
 
16
16
  //#endregion
17
- export { Component, Context, Model, Model as State, def, src_default as default, get, has, map, pending, ref, set, unbind };
17
+ export { Component, Context, Model, def, src_default as default, get, has, map, pending, ref, set, unbind };
18
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 { 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"}
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 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":";;;;;;;;;;;;;AAYA,kBAAe"}
@@ -1,3 +1,5 @@
1
+ import { resolver } from "./context.js";
2
+ import { Renderable, elements } from "./element.js";
1
3
  import { Component } from "./component.js";
2
4
 
3
5
  //#region src/jsx-runtime.d.ts
@@ -105,5 +107,5 @@ declare namespace JSX {
105
107
  } ? T : {};
106
108
  }
107
109
  //#endregion
108
- export { Fragment, Host, HostRuntime, JSX, childrenOf, host, isElement, jsx, jsxDEV, jsxs, propsOf, typeOf };
110
+ export { Fragment, Host, HostRuntime, JSX, type Renderable, childrenOf, elements, host, isElement, jsx, jsxDEV, jsxs, propsOf, resolver, typeOf };
109
111
  //# sourceMappingURL=jsx-runtime.d.ts.map
@@ -1,3 +1,6 @@
1
+ import { resolver } from "./context.js";
2
+ import { elements } from "./element.js";
3
+
1
4
  //#region src/jsx-runtime.ts
2
5
  /**
3
6
  * Agnostic Fragment sentinel. The runtime entries translate it to the host's
@@ -64,5 +67,5 @@ function propsOf(node) {
64
67
  }
65
68
 
66
69
  //#endregion
67
- export { Fragment, childrenOf, host, isElement, jsx, jsxDEV, jsxs, propsOf, typeOf };
70
+ export { Fragment, childrenOf, elements, host, isElement, jsx, jsxDEV, jsxs, propsOf, resolver, typeOf };
68
71
  //# sourceMappingURL=jsx-runtime.js.map
@@ -1 +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"}
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/** Host-side: every class declared an element - see `element.ts`. */\nexport { elements } from './element';\n\n/** Host-side: how `Context.get` resolves outside an origin - see `context.ts`. */\nexport { resolver } from './context';\nexport type { Renderable } from './element';\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;;AAU9D,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/state.d.ts CHANGED
@@ -18,6 +18,12 @@ declare const METHODS: WeakMap<Function, Map<string, (value: any) => void>>;
18
18
  declare const GETTERS: WeakMap<Function, Map<string, () => unknown>>;
19
19
  /** Replacement for a getter captured by live computed properties, for hot patching. */
20
20
  declare const LATEST: WeakMap<Function, Function>;
21
+ type Got<C extends {
22
+ get(...args: any[]): any;
23
+ }> = ReturnType<C['get']> extends infer R ? NonNullable<R> extends Model ? C extends (abstract new (...args: any[]) => infer I) ? I | Extract<R, undefined> : R : R : never;
24
+ type Keyed<C extends {
25
+ get(...args: any[]): any;
26
+ }> = [key: Exclude<Parameters<C['get']>[0], boolean | Function | undefined>, ...rest: Parameters<C['get']> extends [any?, ...infer R] ? R : []];
21
27
  type Overlay<T> = Record<string, unknown> & { [K in Model.Property<T>]?: T[K] extends ((...args: infer A) => infer R) ? (this: T, ...args: A) => R : T[K] };
22
28
  declare namespace Model {
23
29
  /** Any type of Model, using own class constructor as its identifier. */
@@ -249,6 +255,11 @@ declare abstract class Model {
249
255
  * @returns Function to stop watching.
250
256
  */
251
257
  get<T extends typeof Model>(type: T & (typeof Model extends T ? unknown : never), callback: (child: Model) => void | (() => void), downstream: true): () => void;
258
+ /**
259
+ * Fetch through `Type.get(...args)` with this instance as origin - its
260
+ * context, and its subscription when this is a tracking proxy.
261
+ */
262
+ get<C extends Model.Extends>(Type: C, ...args: Keyed<C>): Got<C>;
252
263
  /**
253
264
  * Get update in progress.
254
265
  *
@@ -333,6 +344,17 @@ declare abstract class Model {
333
344
  * @param args - arguments sent to constructor
334
345
  */
335
346
  static new<T extends Model>(this: Model.Type<T>, ...args: Model.Args<T>): T;
347
+ /**
348
+ * Fetch instance of this class from context. Throws if not found.
349
+ *
350
+ * Override with a single signature to accept other arguments - delegate
351
+ * base forms to `super.get(arg)`, and resolve others by calling
352
+ * `Context.get(this, compute)` once, synchronously, so host context and
353
+ * tracking still apply.
354
+ */
355
+ static get<T extends Model>(this: Model.Extends<T>): T;
356
+ /** Fetch instance of this class from context. Undefined if not found. */
357
+ static get<T extends Model>(this: Model.Extends<T>, required: false): T | undefined;
336
358
  /**
337
359
  * Static equivalent of `x instanceof this`.
338
360
  * Determines if provided class is a subtype of this one.
@@ -353,6 +375,7 @@ declare abstract class Model {
353
375
  static on<T extends Model>(this: Model.Extends<T>, setup: NonNullable<Model.On<T>['setup']>): () => boolean;
354
376
  static on<T extends Model>(this: Model.Extends<T>, handler: Model.On<T>): () => boolean;
355
377
  }
378
+ declare function observed<T>(from: Model, key: unknown, value: T): T;
356
379
  /** Bind own configurable methods of a type and collect its reactive getters. */
357
380
  declare function classify(type: Model.Extends, keys: Map<string, (value: any) => void>, getters: Map<string, () => unknown>): void;
358
381
  /**
@@ -391,6 +414,7 @@ declare function children(state: Model, callback: (child: Model) => void): () =>
391
414
  */
392
415
  declare function owned(state: Model, callback: (child: Model) => void | (() => void)): () => undefined;
393
416
  declare function access(state: Model, property: string, required?: boolean): any;
417
+ declare function plain(value: unknown): value is Model.Assign<Model>;
394
418
  /**
395
419
  * Update a property on a state instance and notify listeners.
396
420
  *
@@ -419,5 +443,5 @@ declare function unbind<T extends Function>(fn?: T): T | undefined;
419
443
  declare function parent(child: object): Model | null | undefined;
420
444
  declare function parent(child: object, value: Model | null): boolean;
421
445
  //#endregion
422
- export { GETTERS, type Handler, LATEST, METHODS, Model, PENDING, SETUP, STORE, UNBIND, access, adopt, apply, children, classify, compute, event, owned, parent, trailing, uid, unbind, update };
446
+ export { GETTERS, type Got, type Handler, type Keyed, LATEST, METHODS, Model, PENDING, SETUP, STORE, UNBIND, access, adopt, apply, children, classify, compute, event, observed, owned, parent, plain, trailing, uid, unbind, update };
423
447
  //# sourceMappingURL=state.d.ts.map
package/dist/state.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { REPORT } from "./dispatch.js";
2
2
  import { capture, event, listener, observer, queued, touch, watch } from "./observable.js";
3
- import { Context, host, join } from "./context.js";
3
+ import { Context, host, join, within } from "./context.js";
4
4
 
5
5
  //#region src/state.ts
6
6
  const define = Object.defineProperty;
@@ -53,11 +53,11 @@ var Model = class Model {
53
53
  define(this, "is", { value: this });
54
54
  init(this, args, this.new);
55
55
  }
56
- get(arg1, arg2, arg3) {
56
+ get(arg1, arg2, ...args) {
57
57
  const self = this.is;
58
58
  if (arg1 === void 0) return values(self);
59
59
  if (arg1 === Model) return typeof arg2 == "function" ? owned(self, arg2) : observed(this, arg1, owner(self, arg2));
60
- if (Model.is(arg1)) return observed(this, arg1, Context.get(self).get(arg1, arg2, arg3, self));
60
+ if (Model.is(arg1)) return typeof arg2 == "function" ? Context.get(self).get(arg1, arg2, args[0], self) : within(this, () => arg1.get(arg2, ...args));
61
61
  if (typeof arg1 == "function") return watch(self, unbind(arg1));
62
62
  if (typeof arg2 == "function") return callback(self, arg2, arg1);
63
63
  if (arg1 === null) return observer(self) === null;
@@ -93,6 +93,13 @@ var Model = class Model {
93
93
  event(instance);
94
94
  return instance;
95
95
  }
96
+ static get(required) {
97
+ return Context.get(this, (context, from) => {
98
+ const found = context.get(this, required !== false, void 0, from);
99
+ if (found || required === false) return found || void 0;
100
+ throw new Error(`Could not find ${this} in context.`);
101
+ });
102
+ }
96
103
  /**
97
104
  * Static equivalent of `x instanceof this`.
98
105
  * Determines if provided class is a subtype of this one.
@@ -176,11 +183,12 @@ function init(state, ...args) {
176
183
  listener(state, () => release(null), null);
177
184
  for (let i = 0; i < queue.length; i++) {
178
185
  const arg = queue[i];
179
- const out = typeof arg == "function" ? arg.call(state, state) : arg;
186
+ const called = typeof arg == "function";
187
+ const out = called ? arg.call(state, state) : arg;
180
188
  if (out instanceof Promise) out.catch((err) => report("setup", state, err));
181
189
  else if (Array.isArray(out)) queue.splice(i + 1, 0, ...out);
182
190
  else if (typeof out == "function") listener(state, out, null);
183
- else if (typeof out == "object") assign(state, out, true);
191
+ else if (called ? plain(out) : typeof out == "object") assign(state, out, true);
184
192
  }
185
193
  });
186
194
  if (owns) {
@@ -538,6 +546,11 @@ function access(state, property, required) {
538
546
  stack: error.stack
539
547
  });
540
548
  }
549
+ function plain(value) {
550
+ if (!value || typeof value != "object") return false;
551
+ const proto = Object.getPrototypeOf(value);
552
+ return proto === Object.prototype || proto === null;
553
+ }
541
554
  function assign(state, data, silent) {
542
555
  if (!silent && observer(state) !== null) event(state);
543
556
  const methods = METHODS.get(state.constructor);
@@ -631,5 +644,5 @@ function parent(child, value) {
631
644
  }
632
645
 
633
646
  //#endregion
634
- export { GETTERS, LATEST, METHODS, Model, PENDING, SETUP, STORE, UNBIND, access, adopt, apply, children, classify, compute, event, owned, parent, trailing, uid, unbind, update };
647
+ export { GETTERS, LATEST, METHODS, Model, PENDING, SETUP, STORE, UNBIND, access, adopt, apply, children, classify, compute, event, observed, owned, parent, plain, trailing, uid, unbind, update };
635
648
  //# sourceMappingURL=state.js.map