@expressive/dom 0.7.0 → 0.8.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":"chunk-hot-vusv_ouU.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 { Context, Model, unbind } from '@expressive/mvc';\nimport { watch } from '@expressive/mvc/observable';\nimport { resolver } from '@expressive/mvc/jsx-runtime';\n\nimport { schedule, transition, unschedule } from './scheduler';\nimport type { Schedulable } from './scheduler';\n\ninterface Scope extends Schedulable {\n active: boolean;\n context: Context;\n subscriptions: (() => void)[];\n}\n\nlet current: Scope | undefined;\nlet collecting: (() => void)[] | undefined;\nlet memo: Map<object, object> | undefined;\n\nfunction enter<T>(scope: Scope, render: () => T): T {\n const parent = current;\n const releases = collecting;\n const cached = memo;\n const next: (() => void)[] = [];\n\n current = scope;\n collecting = next;\n memo = new Map();\n\n try {\n return render();\n } finally {\n current = parent;\n collecting = releases;\n memo = cached;\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}\n\nfunction tracked<T extends object>(target: T, required?: boolean): T {\n const scope = current!;\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\ndeclare module '@expressive/mvc' {\n interface Component {\n mount?(): (() => void) | void;\n }\n}\n\nconst normal = resolver((Type, compute) => {\n if (!current) return normal(Type, compute);\n\n const found = compute(Type ? cache(current.context) : current.context);\n\n return found instanceof Model ? cache(found) : found;\n});\n\nfunction cache<T extends object>(target: T): T {\n let proxy = memo!.get(target);\n\n if (!proxy) memo!.set(target, (proxy = tracked(target, false)));\n\n return proxy as T;\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, 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) schedule(scope);\n }\n}\n\nexport { hot, latest, same, track, untrack };\n"],"mappings":"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"}
1
+ {"version":3,"file":"chunk-hot-vusv_ouU.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 { Context, Model, unbind } from '@expressive/mvc';\nimport { watch } from '@expressive/mvc/observable';\nimport { resolver } from '@expressive/mvc/jsx-runtime';\n\nimport { schedule, transition, unschedule } from './scheduler';\nimport type { Schedulable } from './scheduler';\n\ninterface Scope extends Schedulable {\n active: boolean;\n context: Context;\n subscriptions: (() => void)[];\n}\n\nlet current: Scope | undefined;\nlet collecting: (() => void)[] | undefined;\nlet memo: Map<object, object> | undefined;\n\nfunction enter<T>(scope: Scope, render: () => T): T {\n const parent = current;\n const releases = collecting;\n const cached = memo;\n const next: (() => void)[] = [];\n\n current = scope;\n collecting = next;\n memo = new Map();\n\n try {\n return render();\n } finally {\n current = parent;\n collecting = releases;\n memo = cached;\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}\n\nfunction tracked<T extends object>(target: T, required?: boolean): T {\n const scope = current!;\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\nconst normal = resolver((Type, compute) => {\n if (!current) return normal(Type, compute);\n\n const found = compute(Type ? cache(current.context) : current.context);\n\n return found instanceof Model ? cache(found) : found;\n});\n\nfunction cache<T extends object>(target: T): T {\n let proxy = memo!.get(target);\n\n if (!proxy) memo!.set(target, (proxy = tracked(target, false)));\n\n return proxy as T;\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, dispose, enter, owner };\nexport type { Scope };\n","import { owner } from './adapter';\nimport { schedule } from './scheduler';\nimport type { Schedulable } from './scheduler';\n\ninterface Family {\n current: Function;\n scopes: Set<Schedulable>;\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: Schedulable) {\n FAMILY.get(type)?.scopes.add(scope);\n}\n\nfunction untrack(type: Function, scope: Schedulable) {\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) schedule(scope);\n }\n}\n\nexport { hot, latest, same, track, untrack };\n"],"mappings":"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"}
@@ -55,4 +55,4 @@ type Module<T extends ComponentType = ComponentType> = T | {
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-CZ-53pyV.d.ts.map
58
+ //# sourceMappingURL=chunk-loader-CX9ZDjHW.d.ts.map
@@ -3,13 +3,29 @@ import { Fragment } from "@expressive/mvc/jsx-runtime";
3
3
  //#region src/node/vnode.ts
4
4
  const VNODE = Symbol("@expressive/dom.vnode");
5
5
  const PORTAL = Symbol("@expressive/dom.portal");
6
+ const authors = /* @__PURE__ */ new WeakMap();
7
+ let author;
6
8
  function vnode(type, props, key) {
7
- return {
9
+ const node = {
8
10
  [VNODE]: true,
9
11
  type,
10
12
  props: props || {},
11
13
  key
12
14
  };
15
+ if (author) authors.set(node, author);
16
+ return node;
17
+ }
18
+ function authoring(fiber, run) {
19
+ const previous = author;
20
+ author = fiber;
21
+ try {
22
+ return run();
23
+ } finally {
24
+ author = previous;
25
+ }
26
+ }
27
+ function authorOf(value) {
28
+ return isVNode(value) ? authors.get(value) : void 0;
13
29
  }
14
30
  function createElement(type, props, ...children) {
15
31
  const { key, ...rest } = props || {};
@@ -32,5 +48,5 @@ const Fragment$1 = Fragment;
32
48
  const Portal = PORTAL;
33
49
 
34
50
  //#endregion
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-wpCWQ_Zg.js.map
51
+ export { authoring as a, isVNode as c, authorOf as i, vnode as l, PORTAL as n, childrenOf as o, Portal as r, createElement as s, Fragment$1 as t };
52
+ //# sourceMappingURL=chunk-vnode-BN2KOsCV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-vnode-BN2KOsCV.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');\nconst authors = new WeakMap<object, object>();\nlet author: object | undefined;\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 const node: VNode<P> = {\n [VNODE]: true,\n type,\n props: (props || {}) as VNode<P>['props'],\n key: key as Key\n };\n\n if (author) authors.set(node, author);\n return node;\n}\n\nfunction authoring<T>(fiber: object, run: () => T) {\n const previous = author;\n author = fiber;\n\n try {\n return run();\n } finally {\n author = previous;\n }\n}\n\nfunction authorOf(value: unknown) {\n return isVNode(value) ? authors.get(value) : undefined;\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 authoring,\n authorOf,\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;AAC/C,MAAM,0BAAU,IAAI,SAAyB;AAC7C,IAAI;AA8BJ,SAAS,MAAS,MAAwB,OAAU,KAAyB;CAC3E,MAAM,OAAiB;GACpB,QAAQ;EACT;EACA,OAAQ,SAAS,EAAE;EACd;EACN;AAED,KAAI,OAAQ,SAAQ,IAAI,MAAM,OAAO;AACrC,QAAO;;AAGT,SAAS,UAAa,OAAe,KAAc;CACjD,MAAM,WAAW;AACjB,UAAS;AAET,KAAI;AACF,SAAO,KAAK;WACJ;AACR,WAAS;;;AAIb,SAAS,SAAS,OAAgB;AAChC,QAAO,QAAQ,MAAM,GAAG,QAAQ,IAAI,MAAM,GAAG;;AAG/C,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,18 +1,23 @@
1
- import { a as Portal, i as Node, r as Fragment, s as createElement } from "./chunk-loader-CZ-53pyV.js";
1
+ import { a as Portal, i as Node, r as Fragment, s as createElement } from "./chunk-loader-CX9ZDjHW.js";
2
2
  import { JSX } from "./jsx-runtime.js";
3
- import { Component, Context } from "@expressive/mvc";
3
+ import { Component, Context, Model } from "@expressive/mvc";
4
4
 
5
5
  //#region src/style/stylesheet.d.ts
6
6
  type Member = Extract<keyof CSSStyleDeclaration, string>;
7
7
  type Settable = { [K in Member]-?: CSSStyleDeclaration[K] extends Function ? never : K }[Member];
8
- type Key = style.Property | keyof macro.Registry | `--${string}` | `_${string}`;
9
- type Argument<K extends keyof macro.Registry> = macro.Registry[K] extends ((value: infer A, ...rest: any[]) => any) ? A : never;
10
- declare namespace macro {
8
+ type Key = style.Property | keyof macro$1.Registry | `--${string}` | `_${string}` | style.Condition;
9
+ type Argument<K extends keyof macro$1.Registry> = macro$1.Registry[K] extends ((value: infer A, ...rest: any[]) => any) ? A : never;
10
+ declare namespace macro$1 {
11
11
  /**
12
12
  * Macros visible to a style map. A pack augments this interface to declare
13
13
  * what it registers with `macro()`.
14
14
  */
15
15
  interface Registry {}
16
+ /**
17
+ * Registry entries for the macros in a pack, so one line declares them all:
18
+ * `interface Registry extends macro.From<typeof pack> {}`.
19
+ */
20
+ type From<T> = { [K in keyof T as K extends `_${string}` | `$${string}` | '*' ? never : K]: T[K] };
16
21
  /** Maps one argument to style, or to keys which resolve further. */
17
22
  type Fn = (value: any, key: string) => unknown;
18
23
  /**
@@ -25,42 +30,32 @@ declare namespace macro {
25
30
  declare namespace style {
26
31
  /** CSS property names, minus the CSSOM's own members. */
27
32
  type Property = Exclude<Settable, 'length' | 'parentRule' | 'cssText'>;
33
+ /**
34
+ * A state (`:hover`) or environment (`@media …`) key. Its body applies while
35
+ * the condition holds; the host decides how to honour it.
36
+ */
37
+ type Condition = `:${string}` | `@${string}`;
28
38
  /** What a declaration or macro argument may be; never a plain object. */
29
39
  type Value = string | number | boolean | null | undefined | readonly Value[];
30
40
  /**
31
41
  * Body of a `style()` map. Bare keys are declarations or macro calls,
32
- * `_name` opens a rule or descendant scope, and `$name` is reserved.
42
+ * `_name` opens a rule or descendant scope, `:state` and `@media …` apply
43
+ * their body conditionally, and `$name` is reserved.
33
44
  */
34
- type Map = { [K in Key]?: K extends `_${string}` ? Map : K extends keyof macro.Registry ? Argument<K> : Value };
45
+ type Map = { [K in Key]?: K extends `_${string}` | Condition ? Map : K extends keyof macro$1.Registry ? Argument<K> | (undefined extends Argument<K> ? true : never) : Value };
35
46
  }
36
- declare function style<T extends object>(type: T, rules: style.Map): T;
37
- declare function macro(rules: macro.Map): macro.Map;
47
+ declare function style<T extends object>(type: T, ...maps: (style.Map | false | null | undefined)[]): T;
48
+ declare function macro$1(rules: macro$1.Map): macro$1.Map;
38
49
  //#endregion
39
50
  //#region src/style/css.d.ts
40
51
  /**
41
52
  * Web macro pack. Register with `macro(css)` to opt into pixel units for
42
- * numbers and the axis shorthands CSS itself does not provide.
53
+ * numbers and the `size` shorthand.
43
54
  */
44
55
  declare const css: {
45
56
  '*': (value: unknown, key: string) => {
46
57
  [x: string]: unknown;
47
58
  };
48
- mx: (value: style.Value) => {
49
- marginLeft: style.Value;
50
- marginRight: style.Value;
51
- };
52
- my: (value: style.Value) => {
53
- marginTop: style.Value;
54
- marginBottom: style.Value;
55
- };
56
- px: (value: style.Value) => {
57
- paddingLeft: style.Value;
58
- paddingRight: style.Value;
59
- };
60
- py: (value: style.Value) => {
61
- paddingTop: style.Value;
62
- paddingBottom: style.Value;
63
- };
64
59
  size: (value: style.Value) => {
65
60
  width: any;
66
61
  height: any;
@@ -68,21 +63,34 @@ declare const css: {
68
63
  };
69
64
  declare module '@expressive/dom' {
70
65
  namespace macro {
71
- interface Registry {
72
- mx(value: style.Value): style.Map;
73
- my(value: style.Value): style.Map;
74
- px(value: style.Value): style.Map;
75
- py(value: style.Value): style.Map;
76
- size(value: style.Value): style.Map;
77
- }
66
+ interface Registry extends macro.From<typeof css> {}
78
67
  }
79
68
  }
80
69
  //#endregion
70
+ //#region src/style/units.d.ts
71
+ declare const rem: (...values: number[]) => string;
72
+ declare const em: (...values: number[]) => string;
73
+ declare const px: (...values: number[]) => string;
74
+ //#endregion
75
+ //#region src/style/media.d.ts
76
+ interface Query {
77
+ minWidth?: number | string;
78
+ maxWidth?: number | string;
79
+ minHeight?: number | string;
80
+ maxHeight?: number | string;
81
+ orientation?: 'portrait' | 'landscape';
82
+ hover?: 'hover' | 'none';
83
+ pointer?: 'fine' | 'coarse' | 'none';
84
+ prefersColorScheme?: 'light' | 'dark';
85
+ prefersReducedMotion?: 'reduce' | 'no-preference';
86
+ }
87
+ declare function media(query: Query): `@media ${string}`;
88
+ //#endregion
81
89
  //#region src/render/fiber.d.ts
82
90
  type Container = Element | DocumentFragment;
83
91
  //#endregion
84
92
  //#region src/render/render.d.ts
85
93
  declare function render(node: Node, container: Container): () => void;
86
94
  //#endregion
87
- export { Fragment, type JSX, Portal, createElement, css, macro, render, style };
95
+ export { Fragment, type JSX, Portal, createElement, css, em, macro$1 as macro, media, px, rem, render, style };
88
96
  //# sourceMappingURL=index.d.ts.map