sygnal 6.2.0 → 6.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/CHANGELOG.md +112 -0
- package/README.md +3 -1
- package/dist/ai.cjs.js +36 -0
- package/dist/ai.cjs.js.map +1 -1
- package/dist/ai.esm.js +1 -1
- package/dist/astro/index.cjs.js +69 -3
- package/dist/astro/index.cjs.js.map +1 -1
- package/dist/astro/index.mjs +69 -3
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/server.cjs.js +3 -3
- package/dist/astro/server.cjs.js.map +1 -1
- package/dist/astro/server.mjs +3 -3
- package/dist/astro/server.mjs.map +1 -1
- package/dist/diagnostics.cjs.js +211 -11
- package/dist/diagnostics.cjs.js.map +1 -1
- package/dist/diagnostics.esm.js +211 -11
- package/dist/diagnostics.esm.js.map +1 -1
- package/dist/guide/agent.md +7 -1
- package/dist/guide/ai-cards.md +319 -0
- package/dist/guide/ai-chat.md +4 -0
- package/dist/guide/ai-compose.md +881 -0
- package/dist/guide/ai-decisions.md +16 -0
- package/dist/guide/http.md +1 -0
- package/dist/guide/mcp-apps.md +59 -4
- package/dist/index.cjs.js +5704 -350
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +647 -10
- package/dist/index.esm.js +5694 -350
- package/dist/index.esm.js.map +1 -1
- package/dist/sygnal.min.js +1 -1
- package/dist/sygnal.min.js.map +1 -1
- package/dist/vike/config/package.json +1 -1
- package/dist/vike/onRenderClient.cjs.js +3 -2
- package/dist/vike/onRenderClient.cjs.js.map +1 -1
- package/dist/vike/onRenderClient.mjs +3 -2
- package/dist/vike/onRenderClient.mjs.map +1 -1
- package/dist/vite/plugin.cjs.js +69 -3
- package/dist/vite/plugin.cjs.js.map +1 -1
- package/dist/vite/plugin.mjs +69 -3
- package/dist/vite/plugin.mjs.map +1 -1
- package/llms.txt +7 -5
- package/package.json +2 -1
- package/src/ai.d.ts +642 -7
- package/src/ai.ts +6 -0
- package/src/collection.ts +2 -1
- package/src/core/instance.ts +6 -3
- package/src/core/markers/lazy.ts +7 -3
- package/src/core/markers/portal.ts +5 -2
- package/src/core/markers/suspense.ts +3 -2
- package/src/core/markers/transition.ts +6 -3
- package/src/core/registry.ts +9 -5
- package/src/cycle/dom/IsolateModule.ts +25 -22
- package/src/extra/ai/chat/behavior.ts +354 -81
- package/src/extra/ai/chat/driver.ts +7 -4
- package/src/extra/ai/compose/agent.ts +55 -0
- package/src/extra/ai/compose/ask.ts +147 -0
- package/src/extra/ai/compose/behavior.ts +183 -0
- package/src/extra/ai/compose/catalog.ts +211 -0
- package/src/extra/ai/compose/composed.ts +61 -0
- package/src/extra/ai/compose/decisions.ts +1649 -0
- package/src/extra/ai/compose/diag.ts +33 -0
- package/src/extra/ai/compose/index.ts +23 -0
- package/src/extra/ai/compose/layout.ts +441 -0
- package/src/extra/ai/compose/llm.ts +1120 -0
- package/src/extra/ai/compose/render.ts +159 -0
- package/src/extra/ai/compose/testing.ts +71 -0
- package/src/extra/ai/compose/types.ts +159 -0
- package/src/extra/ai/decide.ts +97 -1
- package/src/extra/ai/index.ts +6 -1
- package/src/extra/diagnostics/checks/dom.ts +10 -2
- package/src/extra/diagnostics/checks/next.ts +103 -3
- package/src/extra/diagnostics/checks/persist.ts +4 -2
- package/src/extra/diagnostics/checks/wiring.ts +14 -6
- package/src/extra/diagnostics/codes.ts +59 -0
- package/src/extra/fetchDriver.ts +58 -27
- package/src/extra/lens.ts +15 -0
- package/src/extra/pwa.ts +3 -1
- package/src/extra/reducers.ts +10 -4
- package/src/extra/ssr.ts +3 -3
- package/src/extra/testing.ts +2 -0
- package/src/extra/widget.ts +3 -3
- package/src/index.d.ts +50 -2
- package/src/index.ts +8 -0
- package/src/lazy.ts +3 -2
- package/src/portal.ts +5 -2
- package/src/pragma/index.ts +2 -1
- package/src/suspense.ts +5 -2
- package/src/switchable.ts +2 -1
- package/src/transition.ts +5 -2
- package/src/vike/onRenderClient.ts +3 -2
- package/src/vite/plugin.ts +63 -2
package/src/ai.ts
CHANGED
|
@@ -21,3 +21,9 @@ export {anthropicMessages, agui, fromAISDK, strictSchemas} from './index'
|
|
|
21
21
|
export {makeMcpAppDriver} from './index'
|
|
22
22
|
// A-3 (3-A3, experimental, D291)
|
|
23
23
|
export {formTool} from './index'
|
|
24
|
+
// PLAN-9 (A)
|
|
25
|
+
export {defineCatalog, compose, composeWith, fromTree, toTree, removeNode} from './index'
|
|
26
|
+
// PLAN-9 H: chat client tools and cards
|
|
27
|
+
export {openToolCalls, askCard} from './index'
|
|
28
|
+
// PLAN-9 M-1
|
|
29
|
+
export {Composed} from './index'
|
package/src/collection.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {h} from './cycle/dom/snabbdom';
|
|
2
|
-
// the core's
|
|
2
|
+
// the core's host for this marker, registered on import (D157): unlike Portal, Transition and
|
|
3
|
+
// Suspense (G-751), not on first use, because the lowercase tag works without an import (docs)
|
|
3
4
|
import './core/hosts/collection';
|
|
4
5
|
|
|
5
6
|
/** `<Collection of={Item} from="items" />`: a marker vnode the core's Collection host renders */
|
package/src/core/instance.ts
CHANGED
|
@@ -52,12 +52,15 @@ function extractSlots(children: any[]): [any[], Record<string, any[]>] {
|
|
|
52
52
|
return [slots.default || [], slots]
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* an instance's id among its parent's children (D456): its vnode `key`, else its `id` prop, else
|
|
57
|
+
* its path in the view
|
|
58
|
+
*/
|
|
56
59
|
const idOf = (n: any, path: string) => {
|
|
57
|
-
const id = n.data?.props?.id
|
|
60
|
+
const id = n.key ?? n.data?.props?.id
|
|
58
61
|
let s: any
|
|
59
62
|
// (G-298: an id JSON can't encode, a BigInt, is used as its string)
|
|
60
|
-
if (id) try { s = JSON.stringify(id) } catch (_) { s = String(id) }
|
|
63
|
+
if (id != null) try { s = JSON.stringify(id) } catch (_) { s = String(id) }
|
|
61
64
|
return `${n.sel}::${(s && s.replace(/"/g, '')) || path}`
|
|
62
65
|
}
|
|
63
66
|
|
package/src/core/markers/lazy.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PLAN-4.6 core: lazy() components (R2), registered
|
|
2
|
+
* PLAN-4.6 core: lazy() components (R2), registered by the first `lazy()` call (G-751).
|
|
3
3
|
* A view resolver (registry `resolvers`): until the import resolves, the LazyWrapper itself is
|
|
4
4
|
* the component (it renders the data-sygnal-lazy="loading" placeholder Suspense waits for, or
|
|
5
5
|
* the error placeholder); once it has, the loaded component replaces it under the same id (a
|
|
@@ -15,7 +15,7 @@ import {resolvers} from '../registry'
|
|
|
15
15
|
/** wrapper -> the owners waiting for it (`done`: settled, nobody waits any more) */
|
|
16
16
|
export const waiting = new WeakMap<any, Set<any> & {done?: boolean}>()
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const resolve = (view: any, owner: any) => {
|
|
19
19
|
if (!view.__sygnalLazy) return
|
|
20
20
|
if (view.__sygnalLazyLoaded()) return view.__sygnalLazyLoadedComponent || undefined
|
|
21
21
|
let w = waiting.get(view)
|
|
@@ -37,4 +37,8 @@ resolvers.push((view, owner) => {
|
|
|
37
37
|
set.add(owner)
|
|
38
38
|
owner.dispose$?.().addListener({next: () => set.delete(owner)})
|
|
39
39
|
}
|
|
40
|
-
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let on: any
|
|
43
|
+
/** G-751: registers the resolver once; `lazy()` calls it, not the module's import */
|
|
44
|
+
export const enableLazy = () => { on ||= resolvers.push(resolve) }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PLAN-4.6 core: the Portal marker (R2), registered
|
|
2
|
+
* PLAN-4.6 core: the Portal marker (R2), registered by the public `Portal` when used (G-751).
|
|
3
3
|
* A template rewrite (registry `pres`): the `portal` marker becomes a hidden placeholder whose
|
|
4
4
|
* hooks patch its children into the target with a separate snabbdom patch function. As today
|
|
5
5
|
* (the 5.x core's createPortalPlaceholder):
|
|
@@ -93,4 +93,7 @@ export function portalPlaceholder(target: string, children: any[]): any {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
// (widgets among its children: `pres.widget.$k` rewrites them, extra/widget.ts; the core doesn't walk them)
|
|
97
|
+
const pre = (n: any, o: any, x: string) => portalPlaceholder(n.data?.props?.target, (pres.widget as any)?.$k(n.children || [], o, x) || n.children || [])
|
|
98
|
+
/** G-751: registers the rewrite; the public `Portal` calls it when used (its `$reg`), not on import */
|
|
99
|
+
export const enablePortal = () => { pres.portal = pre }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PLAN-4.6 core: Suspense (R2), registered
|
|
2
|
+
* PLAN-4.6 core: Suspense (R2), registered by the public `Suspense` when used (G-751). A
|
|
3
3
|
* post-processor (registry `posts`) of the injected vnode of an instance whose template has a
|
|
4
4
|
* `suspense` marker (the 5.x core's processSuspensePost):
|
|
5
5
|
* - the core injects a child whose READY is false with data-sygnal-ready="false", and a lazy
|
|
@@ -38,4 +38,5 @@ export function suspensePost(v: any): any {
|
|
|
38
38
|
return out ? {...v, children: out} : v
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
/** G-751: registers the post-processor; the public `Suspense` calls it when used (its `$reg`) */
|
|
42
|
+
export const enableSuspense = () => { posts.suspense = suspensePost }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PLAN-4.6 core: the Transition marker (R2), registered
|
|
3
|
-
*
|
|
2
|
+
* PLAN-4.6 core: the Transition marker (R2), registered by the public `Transition`
|
|
3
|
+
* when used (G-751). A template rewrite (registry `pres`): the `transition` marker is replaced by its first
|
|
4
4
|
* child (walked on, at the marker's path), with snabbdom hooks that add the classes as today
|
|
5
5
|
* (the 5.x core's applyTransitionHooks):
|
|
6
6
|
* `${name}-enter|leave-from` + `-active`, two frames later `-from` becomes `-to`, and at the end
|
|
@@ -57,7 +57,7 @@ export function transitionHooks(vnode: any, p: {name?: string, duration?: number
|
|
|
57
57
|
// (no global symbol registry entry per name)
|
|
58
58
|
const T = Symbol()
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
const pre = (n: any) => {
|
|
61
61
|
const child = n.children?.[0], p = n.data?.props || {}, k = p.name + ' ' + p.duration
|
|
62
62
|
// no element child: the text child (or the marker itself, left as it is: today's behaviour)
|
|
63
63
|
if (!child?.sel) return child || n
|
|
@@ -68,3 +68,6 @@ pres.transition = (n) => {
|
|
|
68
68
|
// fragment or text has no element to animate: nothing happens
|
|
69
69
|
return child.sel == 'collection' ? {...child, data: {...child.data, tr: (v: any) => (v[T] ||= {})[k] ||= transitionHooks(v, p)}} : transitionHooks(child, p)
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
/** G-751: registers the rewrite; the public `Transition` calls it when used (its `$reg`) */
|
|
73
|
+
export const enableTransition = () => { pres.transition = pre }
|
package/src/core/registry.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PLAN-4.6 core: the module registries (04-hooks-contract §2.1). A feature
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* PLAN-4.6 core: the module registries (04-hooks-contract §2.1). A feature fills them when it is
|
|
3
|
+
* used; the core only looks them up, so an app that never uses the feature pays nothing (D157).
|
|
4
|
+
* R2 fills hosts (core/hosts: Collection, Switchable) and the markers (core/markers: Portal,
|
|
5
|
+
* Transition, ClientOnly, Suspense, lazy). G-751: Portal, Transition and Suspense register their
|
|
6
|
+
* handler when a tag uses them (the pragma calls the marker's `$reg`) and `lazy()` its resolver,
|
|
7
|
+
* not on import: a module-level registration is kept by every bundle of the single-file build.
|
|
8
|
+
* Collection and Switchable register on import (the lowercase `<collection>` / `<switchable>`
|
|
9
|
+
* work without one); ClientOnly's is in runtime.ts (sygnal/vike can't reach the registry). R3
|
|
10
|
+
* adds the definition hooks (behaviors, undo, selection, pager, persist, resources).
|
|
7
11
|
*
|
|
8
12
|
* The entries are core modules: they get the owner's raw instance (hooks get InstanceViews).
|
|
9
13
|
*/
|
|
@@ -81,25 +81,25 @@ export class IsolateModule {
|
|
|
81
81
|
|
|
82
82
|
public createModule() {
|
|
83
83
|
const self = this;
|
|
84
|
-
// G-564: a vnode can be in the old tree and the new one (a component's cached
|
|
85
|
-
// Collection item's copy, a hoisted vnode).
|
|
86
|
-
// : <ul>{c}</ul
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
// (
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
const
|
|
84
|
+
// G-564, G-750, G-753: a vnode can be in the old tree and the new one (a component's cached
|
|
85
|
+
// vnode, a Collection item's copy, a hoisted vnode). Under another parent element (a recreated
|
|
86
|
+
// ancestor: `alt ? <ol>{c}</ol> : <ul>{c}</ul>`; a keyed instance moved to another column, or
|
|
87
|
+
// into a new row that takes its old place among its siblings) snabbdom created it again and
|
|
88
|
+
// gave it the new element while the old tree still had it: its destroy hooks saw the new
|
|
89
|
+
// element (a widget inside wasn't unmounted, its scope lost the new element), its old parent
|
|
90
|
+
// removed the new element and left the old one (G-750), or inserted a new sibling before it,
|
|
91
|
+
// inside that sibling (NotFoundError, the patch stopped: G-753). Now an element that is
|
|
92
|
+
// created or patched takes a copy of each child that has an element and isn't one of its old
|
|
93
|
+
// children (only a mounted vnode has one), before it is created: the old tree keeps the vnode
|
|
94
|
+
// and its element. The copy's children array is its own, so its children are copied when it
|
|
95
|
+
// is created. After the patch (post) each vnode takes its copy's fields (its element) and its
|
|
96
|
+
// place again, so the next patch sees the same vnode (snabbdom's shortcut). A patch that
|
|
97
|
+
// throws keeps the copies (pre forgets them): they still work, as copies
|
|
98
|
+
const R: any[] = [];
|
|
99
|
+
const copy = (a: any[], i: number) => { R.push(a, i, a[i]); a[i] = {...a[i], children: a[i].children?.slice()} };
|
|
99
100
|
return {
|
|
100
101
|
pre() {
|
|
101
|
-
|
|
102
|
-
M.clear();
|
|
102
|
+
R.length = 0;
|
|
103
103
|
},
|
|
104
104
|
|
|
105
105
|
create(emptyVNode: VNode, vNode: VNode) {
|
|
@@ -109,7 +109,7 @@ export class IsolateModule {
|
|
|
109
109
|
if (Array.isArray(namespace)) {
|
|
110
110
|
self.insertElement(namespace, elm as Element);
|
|
111
111
|
}
|
|
112
|
-
children?.forEach((c: any) => c?.elm &&
|
|
112
|
+
children?.forEach((c: any, i: number) => c?.elm && copy(children, i));
|
|
113
113
|
},
|
|
114
114
|
|
|
115
115
|
update(oldVNode: VNode, vNode: VNode) {
|
|
@@ -126,21 +126,25 @@ export class IsolateModule {
|
|
|
126
126
|
if (Array.isArray(namespace)) {
|
|
127
127
|
self.insertElement(namespace, elm as Element);
|
|
128
128
|
}
|
|
129
|
+
// (oldVNode !== vNode here: snabbdom returns early for the same vnode; the Set only when a
|
|
130
|
+
// child isn't at its old index)
|
|
131
|
+
const oc = oldVNode.children, nc: any = vNode.children
|
|
132
|
+
let o: any
|
|
133
|
+
nc?.forEach((c: any, i: number) => c?.elm && c !== oc?.[i] && !(o ||= new Set(oc)).has(c) && copy(nc, i));
|
|
129
134
|
},
|
|
130
135
|
|
|
131
|
-
// (the elements as they are now: post runs after the vnodes got their new ones back)
|
|
132
136
|
destroy(vNode: VNode) {
|
|
133
|
-
vNode.children?.forEach(back);
|
|
134
137
|
self.vnodesBeingRemoved.push(vNode.elm as Element);
|
|
135
138
|
},
|
|
136
139
|
|
|
137
140
|
remove(vNode: VNode, cb: Function) {
|
|
138
141
|
self.vnodesBeingRemoved.push(vNode.elm as Element);
|
|
139
|
-
ret();
|
|
140
142
|
cb();
|
|
141
143
|
},
|
|
142
144
|
|
|
143
145
|
post() {
|
|
146
|
+
for (let i = 0; i < R.length; i += 3) R[i][R[i + 1]] = Object.assign(R[i + 2], R[i][R[i + 1]]);
|
|
147
|
+
R.length = 0;
|
|
144
148
|
// G-144: a removed root element is no longer one of its scope's roots (an element no
|
|
145
149
|
// scope has as a root isn't in any set: removing it does nothing)
|
|
146
150
|
for (const elm of self.vnodesBeingRemoved) {
|
|
@@ -148,7 +152,6 @@ export class IsolateModule {
|
|
|
148
152
|
(self.eventDelegator as EventDelegator).removeElement(elm);
|
|
149
153
|
}
|
|
150
154
|
self.vnodesBeingRemoved = [];
|
|
151
|
-
M.clear();
|
|
152
155
|
},
|
|
153
156
|
};
|
|
154
157
|
}
|