@expressive/dom 0.3.0 → 0.4.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 CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ---
8
8
 
9
- `@expressive/dom` renders Expressive MVC without React or Preact. Function components are renderer-stateless: they project props and MVC snapshots into DOM, while `State.get()` and `State.use()` supply dependency tracking and owned state.
9
+ `@expressive/dom` renders Expressive MVC without React or Preact. Function components are renderer-stateless: they project props and MVC snapshots into DOM, while `Model.get()` and `Model.use()` supply dependency tracking and owned state.
10
10
 
11
11
  ```bash
12
12
  npm install @expressive/mvc @expressive/dom
@@ -22,10 +22,10 @@ npm install @expressive/mvc @expressive/dom
22
22
  ```
23
23
 
24
24
  ```tsx
25
- import { State, Component } from '@expressive/mvc';
25
+ import { Model, Component } from '@expressive/mvc';
26
26
  import { render } from '@expressive/dom';
27
27
 
28
- class Counter extends State {
28
+ class Counter extends Model {
29
29
  count = 0;
30
30
  increment() {
31
31
  this.count++;
@@ -68,7 +68,7 @@ Global maps use `macro(map)` and can live in side-effect imports. Register macro
68
68
 
69
69
  Inline style always beats classes; among classes, a caller's rule beats the callee's, and a rule carried through more component `style` props wins - independent of render order. `false`, `null`, and `undefined` omit an entry; `0` remains a macro argument.
70
70
 
71
- `Component` retains the React adapter's model: fields read by `render()` are dependencies, owned instances mount and clean up with the DOM range, and an externally activated instance can be placed directly without transferring ownership.
71
+ `Component` retains the React adapter's semantics: fields read by `render()` are dependencies, owned instances mount and clean up with the DOM range, and an externally activated instance can be placed directly without transferring ownership.
72
72
 
73
73
  The first release includes keyed reconciliation, native events, refs, SVG, `<Component for>` providers, direct `has` / `map` collection rendering, portals, lazy components, error and suspense fallbacks, generated component appearance rules, and retention of committed content while `pending()` work suspends. It deliberately excludes standalone hooks, synthetic events, memo wrappers, SSR, hydration, and build-time style extraction.
74
74
 
@@ -1,31 +1,31 @@
1
- import { Context, State } from "@expressive/mvc";
1
+ import { Context, Model } from "@expressive/mvc";
2
2
 
3
- //#region src/adapter.d.ts
4
- interface UseState extends State {
3
+ //#region src/render/adapter.d.ts
4
+ interface UseModel extends Model {
5
5
  use?(...props: any[]): Promise<void> | void;
6
6
  mount?(): (() => void) | void;
7
7
  }
8
8
  type NoVoid<T> = T extends undefined | void ? null : T;
9
9
  declare module '@expressive/mvc' {
10
- interface UseState extends State {
10
+ interface UseModel extends Model {
11
11
  use?(...props: any[]): Promise<void> | void;
12
12
  mount?(): (() => void) | void;
13
13
  }
14
- namespace State {
14
+ namespace Model {
15
15
  type ForceRefresh = {
16
16
  (): void;
17
17
  <T = void>(waitFor: Promise<T>): Promise<T>;
18
18
  <T = void>(invoke: () => Promise<T>): Promise<T>;
19
19
  };
20
- type GetFactory<T extends State, R> = (this: T, current: T, refresh: ForceRefresh) => R;
21
- type UseArgs<T extends State> = T extends {
20
+ type GetFactory<T extends Model, R> = (this: T, current: T, refresh: ForceRefresh) => R;
21
+ type UseArgs<T extends Model> = T extends {
22
22
  use(...props: infer P): any;
23
- } ? P : State.Args<T>;
24
- function get<T extends State>(this: State.Extends<T>): T;
25
- function get<T extends State>(this: State.Extends<T>, required: false): T | undefined;
26
- function get<T extends State>(this: State.Extends<T>, required: true): Required<T>;
27
- function get<T extends State, R>(this: State.Extends<T>, factory: GetFactory<T, R>): NoVoid<R>;
28
- function use<T extends UseState>(this: State.Type<T>, ...args: UseArgs<T>): T;
23
+ } ? P : Model.Args<T>;
24
+ function get<T extends Model>(this: Model.Extends<T>): T;
25
+ function get<T extends Model>(this: Model.Extends<T>, required: false): T | undefined;
26
+ function get<T extends Model>(this: Model.Extends<T>, required: true): Required<T>;
27
+ function get<T extends Model, R>(this: Model.Extends<T>, factory: GetFactory<T, R>): NoVoid<R>;
28
+ function use<T extends UseModel>(this: Model.Type<T>, ...args: UseArgs<T>): T;
29
29
  }
30
30
  namespace Component {
31
31
  const use: never;
@@ -34,4 +34,4 @@ declare module '@expressive/mvc' {
34
34
  mount?(): (() => void) | void;
35
35
  }
36
36
  }
37
- //# sourceMappingURL=chunk-adapter-4jlvwsge.d.ts.map
37
+ //# sourceMappingURL=chunk-adapter-i1piHw8T.d.ts.map
@@ -1,7 +1,7 @@
1
- import { Component, State, pending, unbind } from "@expressive/mvc";
1
+ import { Component, Model, pending, unbind } from "@expressive/mvc";
2
2
  import { watch } from "@expressive/mvc/observable";
3
3
 
4
- //#region src/scheduler.ts
4
+ //#region src/render/scheduler.ts
5
5
  const urgent = /* @__PURE__ */ new Set();
6
6
  const passive = /* @__PURE__ */ new Set();
7
7
  const after = [];
@@ -132,7 +132,7 @@ function unschedule(scope) {
132
132
  }
133
133
 
134
134
  //#endregion
135
- //#region src/adapter.ts
135
+ //#region src/render/adapter.ts
136
136
  let current;
137
137
  let collecting;
138
138
  function enter(scope, render) {
@@ -146,7 +146,7 @@ function enter(scope, render) {
146
146
  try {
147
147
  const output = render();
148
148
  if (scope.kind == "function" && scope.useIndex !== scope.uses.length) {
149
- if (!scope.hot) throw new Error("State.use() calls must keep the same order on every function-component render.");
149
+ if (!scope.hot) throw new Error("Model.use() calls must keep the same order on every function-component render.");
150
150
  truncate(scope, scope.useIndex);
151
151
  }
152
152
  return output;
@@ -165,7 +165,7 @@ function dispose(scope) {
165
165
  scope.subscriptions = [];
166
166
  truncate(scope, 0);
167
167
  }
168
- /** Destroy the `State.use()` slots of a scope from `index` on. */
168
+ /** Destroy the `Model.use()` slots of a scope from `index` on. */
169
169
  function truncate(scope, index) {
170
170
  for (let i = scope.uses.length - 1; i >= index; i--) {
171
171
  const slot = scope.uses[i];
@@ -183,7 +183,7 @@ function commit(scope) {
183
183
  }
184
184
  }
185
185
  function requireScope() {
186
- if (!current) throw new Error("State.get() and State.use() may only run while @expressive/dom is rendering.");
186
+ if (!current) throw new Error("Model.get() and Model.use() may only run while @expressive/dom is rendering.");
187
187
  return current;
188
188
  }
189
189
  function tracked(target, required) {
@@ -198,7 +198,7 @@ function tracked(target, required) {
198
198
  collecting.push(release);
199
199
  return proxy;
200
200
  }
201
- State.get = function get(argument) {
201
+ Model.get = function get(argument) {
202
202
  const scope = requireScope();
203
203
  const instance = scope.childContext.get(this, argument === false ? false : true);
204
204
  if (!instance) return void 0;
@@ -211,13 +211,13 @@ State.get = function get(argument) {
211
211
  });
212
212
  return argument.call(proxy, proxy, refresh) ?? null;
213
213
  };
214
- State.use = function use(...args) {
214
+ Model.use = function use(...args) {
215
215
  const scope = requireScope();
216
- if (scope.kind != "function") throw new Error("State.use() is only available at the top level of a function component.");
216
+ if (scope.kind != "function") throw new Error("Model.use() is only available at the top level of a function component.");
217
217
  const index = scope.useIndex++;
218
218
  let slot = scope.uses[index];
219
219
  if (slot && slot.Type !== this) {
220
- if (!scope.hot) throw new Error("State.use() calls must keep the same order on every function-component render.");
220
+ if (!scope.hot) throw new Error("Model.use() calls must keep the same order on every function-component render.");
221
221
  truncate(scope, index);
222
222
  slot = void 0;
223
223
  }
@@ -262,7 +262,7 @@ Object.defineProperty(Component, "use", {
262
262
  }
263
263
  });
264
264
  const OWNERS = /* @__PURE__ */ new WeakMap();
265
- State.on({ method(key, fn, owner) {
265
+ Model.on({ method(key, fn, owner) {
266
266
  if (/^[A-Z]/.test(key)) OWNERS.set(fn, {
267
267
  owner,
268
268
  key
@@ -279,7 +279,7 @@ function owner(type) {
279
279
  }
280
280
 
281
281
  //#endregion
282
- //#region src/hot.ts
282
+ //#region src/render/hot.ts
283
283
  const FAMILIES = /* @__PURE__ */ new Map();
284
284
  const FAMILY = /* @__PURE__ */ new WeakMap();
285
285
  /** The latest implementation of a component registered for hot refresh. */
@@ -328,4 +328,4 @@ function hot(id, components) {
328
328
 
329
329
  //#endregion
330
330
  export { untrack as a, dispose as c, claim as d, release as f, transition as h, track as i, enter as l, settle as m, latest as n, call as o, schedule as p, same as r, commit as s, hot as t, afterFlush as u };
331
- //# sourceMappingURL=chunk-hot-BAqPvKEQ.js.map
331
+ //# sourceMappingURL=chunk-hot-9LhRiwFx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-hot-9LhRiwFx.js","names":[],"sources":["../src/render/scheduler.ts","../src/render/adapter.ts","../src/render/hot.ts"],"sourcesContent":["import { pending } from '@expressive/mvc';\n\ninterface Schedulable {\n queued?: 'urgent' | 'passive' | 'deferred';\n holds?: (() => void)[];\n probed?: { output: unknown };\n blocking?: (() => void)[];\n update(passive: boolean): PromiseLike<unknown> | void;\n probe?(): PromiseLike<unknown> | void;\n empty?(): boolean;\n}\n\nconst urgent = new Set<Schedulable>();\nconst passive = new Set<Schedulable>();\nconst after: (() => void)[] = [];\n\nlet depth = 0;\nlet urgentQueued = false;\nlet passiveQueued = false;\n\nfunction flush(scopes: Set<Schedulable>) {\n for (const scope of scopes) {\n scopes.delete(scope);\n scope.queued = undefined;\n\n let waiting: PromiseLike<unknown> | void = undefined;\n\n try {\n waiting = scope.update(false);\n } catch (error) {\n console.error(error);\n }\n\n settle(scope);\n if (!waiting) unblock(scope);\n }\n}\n\nfunction flushUrgent() {\n urgentQueued = false;\n flush(urgent);\n\n for (const run of after.splice(0)) run();\n}\n\nfunction afterFlush(run: () => void) {\n after.push(run);\n\n if (!urgentQueued) {\n urgentQueued = true;\n queueMicrotask(flushUrgent);\n }\n}\n\nfunction flushPassive() {\n passiveQueued = false;\n\n const batch = [...passive].filter((scope) => scope.queued === 'passive');\n passive.clear();\n\n for (const scope of batch) {\n const waiting = scope.probe?.();\n if (waiting) return defer(batch, waiting, scope);\n }\n\n batch.sort((a, b) => Number(!!b.empty?.()) - Number(!!a.empty?.()));\n\n for (let index = 0; index < batch.length; index++) {\n const scope = batch[index];\n\n if (scope.queued !== 'passive') continue;\n\n scope.queued = undefined;\n\n let waiting: PromiseLike<unknown> | void = undefined;\n\n try {\n waiting = scope.update(true);\n } catch (error) {\n console.error(error);\n }\n\n settle(scope);\n\n if (waiting) return defer(batch.slice(index + 1), waiting, scope);\n unblock(scope);\n }\n}\n\nfunction defer(scopes: Schedulable[], waiting: PromiseLike<unknown>, source: Schedulable) {\n const held = scopes.filter((scope) => scope.queued === 'passive');\n\n for (const scope of held) {\n scope.queued = 'deferred';\n scope.probed = undefined;\n }\n\n const resume = () => {\n for (const scope of held)\n if (scope.queued === 'deferred') {\n scope.queued = undefined;\n transition(() => schedule(scope));\n }\n };\n\n (source.blocking ||= []).push(resume);\n waiting.then(resume, resume);\n}\n\nfunction unblock(scope: Schedulable) {\n const { blocking } = scope;\n\n scope.blocking = undefined;\n blocking?.forEach((resume) => resume());\n}\n\nfunction release(holds?: (() => void)[]) {\n holds?.forEach((held) => held());\n}\n\nfunction settle(scope: Schedulable) {\n const { holds } = scope;\n\n scope.holds = undefined;\n release(holds);\n}\n\nfunction schedule(scope: Schedulable) {\n const held = pending();\n\n if (held) (scope.holds ||= []).push(held);\n scope.probed = undefined;\n\n if (!depth) {\n passive.delete(scope);\n scope.queued = 'urgent';\n urgent.add(scope);\n\n if (!urgentQueued) {\n urgentQueued = true;\n queueMicrotask(flushUrgent);\n }\n\n return;\n }\n\n if (scope.queued && scope.queued !== 'deferred') return;\n\n scope.queued = 'passive';\n passive.add(scope);\n\n if (!passiveQueued) {\n passiveQueued = true;\n setTimeout(flushPassive);\n }\n}\n\nfunction transition(work: () => void) {\n depth++;\n\n try {\n work();\n } finally {\n depth--;\n }\n}\n\nfunction claim(scope: Schedulable) {\n urgent.delete(scope);\n passive.delete(scope);\n scope.queued = undefined;\n scope.probed = undefined;\n}\n\nfunction unschedule(scope: Schedulable) {\n urgent.delete(scope);\n passive.delete(scope);\n scope.queued = undefined;\n scope.probed = undefined;\n settle(scope);\n unblock(scope);\n}\n\nexport { afterFlush, claim, release, schedule, settle, transition, unschedule };\nexport type { Schedulable };\n","import { Component, Context, Model, unbind } from '@expressive/mvc';\nimport { watch } from '@expressive/mvc/observable';\n\nimport { schedule, transition, unschedule } from './scheduler';\nimport type { Schedulable } from './scheduler';\n\ninterface UseModel extends Model {\n use?(...props: any[]): Promise<void> | void;\n mount?(): (() => void) | void;\n}\n\ninterface UseSlot {\n Type: Model.Type;\n context: Context;\n instance: UseModel;\n proxy: Model;\n release: () => void;\n mounted?: true;\n cleanup?: (() => void) | void;\n apply: (...args: any[]) => unknown;\n}\n\ninterface Scope extends Schedulable {\n active: boolean;\n childContext: Context;\n context: Context;\n hot?: boolean;\n kind: 'component' | 'function' | 'collection';\n subscriptions: (() => void)[];\n uses: UseSlot[];\n useIndex: number;\n}\n\nlet current: Scope | undefined;\nlet collecting: (() => void)[] | undefined;\n\nfunction enter<T>(scope: Scope, render: () => T): T {\n const parent = current;\n const releases = collecting;\n const next: (() => void)[] = [];\n\n current = scope;\n collecting = next;\n scope.childContext = scope.context;\n scope.useIndex = 0;\n\n try {\n const output = render();\n\n if (scope.kind == 'function' && scope.useIndex !== scope.uses.length) {\n if (!scope.hot)\n throw new Error('Model.use() calls must keep the same order on every function-component render.');\n\n truncate(scope, scope.useIndex);\n }\n\n return output;\n } finally {\n scope.hot = undefined;\n current = parent;\n collecting = releases;\n scope.subscriptions.forEach((release) => release());\n scope.subscriptions = next;\n }\n}\n\nfunction dispose(scope: Scope) {\n scope.active = false;\n unschedule(scope);\n scope.subscriptions.forEach((release) => release());\n scope.subscriptions = [];\n truncate(scope, 0);\n}\n\n/** Destroy the `Model.use()` slots of a scope from `index` on. */\nfunction truncate(scope: Scope, index: number) {\n for (let i = scope.uses.length - 1; i >= index; i--) {\n const slot = scope.uses[i];\n\n slot.release();\n if (typeof slot.cleanup == 'function') slot.cleanup();\n slot.context.pop();\n slot.instance.set(null);\n }\n\n scope.uses.length = index;\n}\n\nfunction commit(scope: Scope) {\n for (const slot of scope.uses)\n if (!slot.mounted) {\n slot.mounted = true;\n slot.cleanup = slot.instance.mount?.();\n }\n}\n\nfunction requireScope(): Scope {\n if (!current)\n throw new Error('Model.get() and Model.use() may only run while @expressive/dom is rendering.');\n\n return current;\n}\n\nfunction tracked<T extends object>(target: T, required?: boolean): T {\n const scope = requireScope();\n let proxy = target;\n let first = true;\n\n const release = watch(\n target,\n (next) => {\n proxy = next;\n if (!first && scope.active) schedule(scope);\n first = false;\n },\n required,\n transition\n );\n\n collecting!.push(release);\n return proxy;\n}\n\ntype NoVoid<T> = T extends undefined | void ? null : T;\n\ndeclare module '@expressive/mvc' {\n interface UseModel extends Model {\n use?(...props: any[]): Promise<void> | void;\n mount?(): (() => void) | void;\n }\n\n namespace Model {\n type ForceRefresh = {\n (): void;\n <T = void>(waitFor: Promise<T>): Promise<T>;\n <T = void>(invoke: () => Promise<T>): Promise<T>;\n };\n\n type GetFactory<T extends Model, R> = (\n this: T,\n current: T,\n refresh: ForceRefresh\n ) => R;\n\n type UseArgs<T extends Model> = T extends { use(...props: infer P): any }\n ? P\n : Model.Args<T>;\n\n function get<T extends Model>(this: Model.Extends<T>): T;\n function get<T extends Model>(this: Model.Extends<T>, required: false): T | undefined;\n function get<T extends Model>(this: Model.Extends<T>, required: true): Required<T>;\n function get<T extends Model, R>(\n this: Model.Extends<T>,\n factory: GetFactory<T, R>\n ): NoVoid<R>;\n function use<T extends UseModel>(\n this: Model.Type<T>,\n ...args: UseArgs<T>\n ): T;\n }\n\n namespace Component {\n const use: never;\n }\n\n interface Component {\n mount?(): (() => void) | void;\n }\n}\n\n(Model as any).get = function get<T extends Model>(\n this: Model.Extends<T>,\n argument?: boolean | Model.GetFactory<T, unknown>\n) {\n const scope = requireScope();\n const instance = scope.childContext.get(this, argument === false ? false : true);\n\n if (!instance) return undefined;\n\n const proxy = tracked(instance, argument === true);\n\n if (typeof argument != 'function') return proxy;\n\n const refresh = ((action?: Promise<unknown> | (() => Promise<unknown>)) => {\n if (typeof action == 'function') action = action();\n schedule(scope);\n return action instanceof Promise ? action.finally(() => schedule(scope)) : undefined;\n }) as Model.ForceRefresh;\n\n return argument.call(proxy, proxy, refresh) ?? null;\n};\n\n(Model as any).use = function use<T extends UseModel>(\n this: Model.Type<T>,\n ...args: Model.UseArgs<T>\n) {\n const scope = requireScope();\n\n if (scope.kind != 'function')\n throw new Error('Model.use() is only available at the top level of a function component.');\n\n const index = scope.useIndex++;\n let slot = scope.uses[index] as UseSlot | undefined;\n\n if (slot && slot.Type !== this) {\n if (!scope.hot)\n throw new Error('Model.use() calls must keep the same order on every function-component render.');\n\n truncate(scope, index);\n slot = undefined;\n }\n\n if (!slot) {\n let instance!: T;\n const assign = (value: unknown) =>\n typeof value == 'object' && value && instance.set(value as Model.Assign<T>);\n let apply: (...values: any[]) => unknown = (...values) =>\n Promise.all(values.flat().map(assign));\n\n instance = new (this as any)((self: T) => {\n const own = self as T & UseModel;\n\n if (typeof own.use == 'function') {\n apply = own.use.bind(own);\n apply(...args);\n return;\n }\n\n return args;\n });\n const context = scope.childContext.push(instance);\n\n slot = {\n Type: this,\n context,\n instance,\n proxy: instance,\n release: undefined!,\n apply\n };\n\n let first = true;\n slot.release = watch(instance, (proxy) => {\n slot!.proxy = proxy;\n\n if (!first && scope.active) schedule(scope);\n first = false;\n }, undefined, transition);\n\n slot.apply = apply;\n scope.uses.push(slot);\n } else {\n slot.apply(...args);\n }\n\n scope.childContext = slot.context;\n return slot.proxy as T;\n};\n\nObject.defineProperty(Component, 'use', {\n configurable: true,\n value() {\n throw new Error(`${this} is a Component - render it instead of calling use().`);\n }\n});\n\nconst OWNERS = new WeakMap<Function, { owner: Model; key: string }>();\n\nModel.on({\n method(key, fn, owner) {\n if (/^[A-Z]/.test(key)) OWNERS.set(fn, { owner, key });\n }\n});\n\nfunction call(type: Function, props: unknown) {\n const sub = OWNERS.get(type);\n\n if (!sub) return type(props);\n\n const { owner, key } = sub;\n return unbind((owner as any)[key]).call(tracked(owner), props);\n}\n\nfunction owner(type: unknown) {\n return typeof type == 'function' ? OWNERS.get(type) : undefined;\n}\n\nexport { call, commit, dispose, enter, owner };\nexport type { Scope };\n","import type { Scope } from './adapter';\nimport { owner } from './adapter';\nimport { schedule } from './scheduler';\n\ninterface Family {\n current: Function;\n scopes: Set<Scope>;\n}\n\nconst FAMILIES = new Map<string, Family>();\nconst FAMILY = new WeakMap<Function, Family>();\n\n/** The latest implementation of a component registered for hot refresh. */\nfunction latest(type: Function) {\n return FAMILY.get(type)?.current || type;\n}\n\n/** Whether two element types are one component, across hot edits. */\nfunction same(a: unknown, b: unknown) {\n if (a === b) return true;\n\n const sub = owner(a);\n\n if (sub) {\n const other = owner(b);\n return !!other && other.owner === sub.owner && other.key === sub.key;\n }\n\n const family = typeof a == 'function' && FAMILY.get(a);\n\n return !!family && family === FAMILY.get(b as Function);\n}\n\nfunction track(type: Function, scope: Scope) {\n FAMILY.get(type)?.scopes.add(scope);\n}\n\nfunction untrack(type: Function, scope: Scope) {\n FAMILY.get(type)?.scopes.delete(scope);\n}\n\n/**\n * Register a module's function components under stable ids. A component seen\n * before takes its new implementation and re-renders where it is mounted.\n */\nfunction hot(id: string, components: Record<string, unknown>) {\n for (const [name, type] of Object.entries(components)) {\n if (typeof type != 'function') continue;\n\n const key = `${id}#${name}`;\n let family = FAMILIES.get(key);\n\n if (!family) FAMILIES.set(key, (family = { current: type, scopes: new Set() }));\n\n FAMILY.set(type, family);\n\n if (family.current === type) continue;\n\n family.current = type;\n\n for (const scope of family.scopes) {\n scope.hot = true;\n schedule(scope);\n }\n }\n}\n\nexport { hot, latest, same, track, untrack };\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { JSX } from "./jsx-runtime.js";
2
2
  import { has, map } from "@expressive/mvc";
3
3
 
4
- //#region src/vnode.d.ts
4
+ //#region src/node/vnode.d.ts
5
5
  declare const VNODE: unique symbol;
6
6
  type Key = string | number | null | undefined;
7
7
  type FunctionComponent<P = any> = (props: P) => Node;
@@ -48,11 +48,11 @@ declare const Portal: (props: {
48
48
  children?: Node;
49
49
  }) => Node;
50
50
  //#endregion
51
- //#region src/loader.d.ts
51
+ //#region src/node/loader.d.ts
52
52
  type Module<T extends ComponentType = ComponentType> = T | {
53
53
  default: T;
54
54
  };
55
55
  type Attributes<T> = [T] extends [never] ? {} : T extends (abstract new (...args: any[]) => infer I) ? JSX.LibraryManagedAttributes<T, I> : T extends ((props: infer P) => any) ? P : never;
56
56
  //#endregion
57
57
  export { Portal as a, vnode as c, Node as i, Module as n, VNode as o, Fragment as r, createElement as s, Attributes as t };
58
- //# sourceMappingURL=chunk-loader-kjuM318E.d.ts.map
58
+ //# sourceMappingURL=chunk-loader-CZ-53pyV.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { Fragment } from "@expressive/mvc/jsx-runtime";
2
2
 
3
- //#region src/vnode.ts
3
+ //#region src/node/vnode.ts
4
4
  const VNODE = Symbol("@expressive/dom.vnode");
5
5
  const PORTAL = Symbol("@expressive/dom.portal");
6
6
  function vnode(type, props, key) {
@@ -33,4 +33,4 @@ const Portal = PORTAL;
33
33
 
34
34
  //#endregion
35
35
  export { createElement as a, childrenOf as i, PORTAL as n, isVNode as o, Portal as r, vnode as s, Fragment$1 as t };
36
- //# sourceMappingURL=chunk-vnode-BG1Cv8F9.js.map
36
+ //# sourceMappingURL=chunk-vnode-wpCWQ_Zg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-vnode-wpCWQ_Zg.js","names":["Fragment","FRAGMENT"],"sources":["../src/node/vnode.ts"],"sourcesContent":["import { Fragment as FRAGMENT } from '@expressive/mvc/jsx-runtime';\nimport type { has, map } from '@expressive/mvc';\nimport type { JSX as Runtime } from '../jsx-runtime';\n\nconst VNODE = Symbol('@expressive/dom.vnode');\nconst PORTAL = Symbol('@expressive/dom.portal');\n\ntype Key = string | number | null | undefined;\ntype FunctionComponent<P = any> = (props: P) => Node;\ninterface ComponentInstance {\n render(props?: any): Node;\n}\ntype ComponentType<P = any> = FunctionComponent<P> | (abstract new (...args: any[]) => object);\n\ntype Node =\n | VNode\n | ComponentInstance\n | string\n | number\n | bigint\n | boolean\n | null\n | undefined\n | readonly Node[]\n | has.List<Node>\n | has.Pool<Node, any, any>\n | map.Managed<unknown, Node>;\n\ninterface VNode<P = any> {\n readonly [VNODE]: true;\n readonly type: string | symbol | ComponentType<P>;\n readonly props: P & { children?: Node };\n readonly key?: Key;\n}\n\nfunction vnode<P>(type: VNode<P>['type'], props: P, key?: unknown): VNode<P> {\n return {\n [VNODE]: true,\n type,\n props: (props || {}) as VNode<P>['props'],\n key: key as Key\n };\n}\n\nfunction createElement(type: VNode['type'], props?: Record<string, unknown> | null, ...children: unknown[]): VNode {\n const { key, ...rest } = props || {};\n\n if (children.length) rest.children = children.length == 1 ? children[0] : children;\n\n return vnode(type, rest, key);\n}\n\ntype JsxElement = Runtime.Element;\ntype JsxElementType = Runtime.ElementType;\ntype JsxElementClass = Runtime.ElementClass;\ntype JsxAttributesProperty = Runtime.ElementAttributesProperty;\ntype JsxManaged<C, P> = Runtime.LibraryManagedAttributes<C, P>;\ntype JsxChildrenAttribute = Runtime.ElementChildrenAttribute;\ntype JsxIntrinsicAttributes = Runtime.IntrinsicAttributes;\ntype JsxIntrinsicElements = Runtime.IntrinsicElements;\n\ndeclare namespace createElement {\n namespace JSX {\n type Element = JsxElement;\n type ElementType = JsxElementType;\n interface ElementClass extends JsxElementClass {}\n interface ElementAttributesProperty extends JsxAttributesProperty {}\n type LibraryManagedAttributes<C, P> = JsxManaged<C, P>;\n interface ElementChildrenAttribute extends JsxChildrenAttribute {}\n interface IntrinsicAttributes extends JsxIntrinsicAttributes {}\n type IntrinsicElements = JsxIntrinsicElements;\n }\n}\n\nfunction isVNode(value: unknown): value is VNode {\n return !!value && typeof value == 'object' && (value as VNode)[VNODE] === true;\n}\n\nfunction childrenOf(value: unknown): Node[] {\n const output: Node[] = [];\n\n function add(child: unknown) {\n if (Array.isArray(child)) child.forEach(add);\n else if (child !== null && child !== undefined && typeof child != 'boolean')\n output.push(child as Node);\n }\n\n add(value);\n return output;\n}\n\nconst Fragment = FRAGMENT as unknown as (props: { children?: Node }) => Node;\nconst Portal = PORTAL as unknown as (props: { into: Element | DocumentFragment | string; children?: Node }) => Node;\n\nexport {\n VNODE,\n PORTAL,\n childrenOf,\n createElement,\n Fragment,\n Portal,\n isVNode,\n vnode\n};\n\nexport type { ComponentInstance, ComponentType, FunctionComponent, Key, Node, VNode };\n"],"mappings":";;;AAIA,MAAM,QAAQ,OAAO,wBAAwB;AAC7C,MAAM,SAAS,OAAO,yBAAyB;AA8B/C,SAAS,MAAS,MAAwB,OAAU,KAAyB;AAC3E,QAAO;GACJ,QAAQ;EACT;EACA,OAAQ,SAAS,EAAE;EACd;EACN;;AAGH,SAAS,cAAc,MAAqB,OAAwC,GAAG,UAA4B;CACjH,MAAM,EAAE,KAAK,GAAG,SAAS,SAAS,EAAE;AAEpC,KAAI,SAAS,OAAQ,MAAK,WAAW,SAAS,UAAU,IAAI,SAAS,KAAK;AAE1E,QAAO,MAAM,MAAM,MAAM,IAAI;;AAyB/B,SAAS,QAAQ,OAAgC;AAC/C,QAAO,CAAC,CAAC,SAAS,OAAO,SAAS,YAAa,MAAgB,WAAW;;AAG5E,SAAS,WAAW,OAAwB;CAC1C,MAAM,SAAiB,EAAE;CAEzB,SAAS,IAAI,OAAgB;AAC3B,MAAI,MAAM,QAAQ,MAAM,CAAE,OAAM,QAAQ,IAAI;WACnC,UAAU,QAAQ,UAAU,UAAa,OAAO,SAAS,UAChE,QAAO,KAAK,MAAc;;AAG9B,KAAI,MAAM;AACV,QAAO;;AAGT,MAAMA,aAAWC;AACjB,MAAM,SAAS"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { a as Portal, i as Node, r as Fragment, s as createElement } from "./chunk-loader-kjuM318E.js";
1
+ import { a as Portal, i as Node, r as Fragment, s as createElement } from "./chunk-loader-CZ-53pyV.js";
2
2
  import { JSX } from "./jsx-runtime.js";
3
+ import { Context, Model } from "@expressive/mvc";
3
4
 
4
- //#region src/stylesheet.d.ts
5
+ //#region src/style/stylesheet.d.ts
5
6
  type Member = Extract<keyof CSSStyleDeclaration, string>;
6
7
  type Settable = { [K in Member]-?: CSSStyleDeclaration[K] extends Function ? never : K }[Member];
7
8
  type Key = style.Property | keyof macro.Registry | `--${string}` | `_${string}`;
@@ -35,7 +36,7 @@ declare namespace style {
35
36
  declare function style<T extends object>(type: T, rules: style.Map): T;
36
37
  declare function macro(rules: macro.Map): macro.Map;
37
38
  //#endregion
38
- //#region src/css.d.ts
39
+ //#region src/style/css.d.ts
39
40
  /**
40
41
  * Web macro pack. Register with `macro(css)` to opt into pixel units for
41
42
  * numbers and the axis shorthands CSS itself does not provide.
@@ -77,8 +78,10 @@ declare module '@expressive/dom' {
77
78
  }
78
79
  }
79
80
  //#endregion
80
- //#region src/render.d.ts
81
+ //#region src/render/fiber.d.ts
81
82
  type Container = Element | DocumentFragment;
83
+ //#endregion
84
+ //#region src/render/render.d.ts
82
85
  declare function render(node: Node, container: Container): () => void;
83
86
  //#endregion
84
87
  export { Fragment, type JSX, Portal, createElement, css, macro, render, style };