sygnal 6.3.0 → 6.5.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 +91 -0
- 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 -2
- package/dist/astro/server.cjs.js.map +1 -1
- package/dist/astro/server.mjs +3 -2
- package/dist/astro/server.mjs.map +1 -1
- package/dist/diagnostics.cjs.js +105 -19
- package/dist/diagnostics.cjs.js.map +1 -1
- package/dist/diagnostics.esm.js +105 -19
- package/dist/diagnostics.esm.js.map +1 -1
- package/dist/guide/mcp-apps.md +59 -4
- package/dist/index.cjs.js +54 -25
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +27 -6
- package/dist/index.esm.js +54 -25
- 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/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 +4 -4
- package/package.json +1 -1
- package/src/core/cell.ts +25 -7
- package/src/core/hosts/collection.ts +6 -11
- package/src/core/hosts/switchable.ts +2 -2
- package/src/core/instance.ts +2 -2
- package/src/extra/diagnostics/checks/collections.ts +31 -25
- package/src/extra/diagnostics/checks/dom.ts +10 -2
- package/src/extra/diagnostics/checks/next.ts +39 -1
- package/src/extra/diagnostics/checks/persist.ts +4 -2
- package/src/extra/diagnostics/checks/wiring.ts +14 -6
- package/src/extra/diagnostics/codes.ts +9 -0
- package/src/extra/pwa.ts +3 -1
- package/src/extra/reducers.ts +10 -4
- package/src/index.d.ts +26 -5
- package/src/vite/plugin.ts +63 -2
package/dist/vite/plugin.cjs.js
CHANGED
|
@@ -742,6 +742,12 @@ if (import.meta.hot) installMcpBridge(import.meta.hot, { agentTools, confirm: ${
|
|
|
742
742
|
* /__sygnal/mcp (./mcp.ts: streamable HTTP, loopback / local Host / local Origin only)
|
|
743
743
|
* and the dev entries also import 'virtual:sygnal/mcp', which connects the page over the
|
|
744
744
|
* HMR channel (installMcpBridge from 'sygnal/devtools'). Never in `vite build` or Vitest.
|
|
745
|
+
* 11. SYG103 view words (dev server with diagnostics on; never `vite build`, SSR or Vitest): a
|
|
746
|
+
* module that sets `X.intent` or `X.uses` gets a tail registering, for each such X, the
|
|
747
|
+
* words of its string literals and of the relative modules it imports, in
|
|
748
|
+
* `globalThis.__SYGNAL_VIEW_TOKENS__`. The runtime SYG103 check then takes a selector drawn
|
|
749
|
+
* by a view helper (`{state.open && panel()}`) as conditionally rendered, as it does for
|
|
750
|
+
* markup in the view function itself (see viewTokensTail).
|
|
745
751
|
*
|
|
746
752
|
* Why not Vite's `define`? Vite's dependency optimizer does not apply user
|
|
747
753
|
* `define` replacements to pre-bundled dependencies (only process.env.NODE_ENV),
|
|
@@ -979,9 +985,20 @@ function sygnal(options = {}) {
|
|
|
979
985
|
transform(code, id, opts) {
|
|
980
986
|
// SYG666 (PLAN-5 W-2): an adapter entry imported without its optional peers; every mode
|
|
981
987
|
const adapters = adapterImports(this, code, id);
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
988
|
+
const result = adapters
|
|
989
|
+
? checkPeers(this, adapters, id).then(() => devTransform.call(this, code, id, opts))
|
|
990
|
+
: devTransform.call(this, code, id, opts);
|
|
991
|
+
// 11. the words SYG103 may take as conditionally rendered markup (dev server, diagnostics on)
|
|
992
|
+
const tokens = isServe && !isVitest && devOn && !opts?.ssr ? viewTokensTail(this, code, id) : null;
|
|
993
|
+
if (!tokens)
|
|
994
|
+
return result;
|
|
995
|
+
return Promise.all([result, tokens]).then(([r, tail]) => {
|
|
996
|
+
if (!tail)
|
|
997
|
+
return r;
|
|
998
|
+
if (r == null)
|
|
999
|
+
return withSourcemap(code, [], tail, id);
|
|
1000
|
+
return typeof r == 'string' ? r + tail : { ...r, code: r.code + tail };
|
|
1001
|
+
});
|
|
985
1002
|
},
|
|
986
1003
|
};
|
|
987
1004
|
function devTransform(code, id, opts) {
|
|
@@ -1064,6 +1081,55 @@ function sygnal(options = {}) {
|
|
|
1064
1081
|
return done();
|
|
1065
1082
|
}
|
|
1066
1083
|
}
|
|
1084
|
+
// 11. SYG103 (the dev runtime check of an intent selector that never matched) lets a selector
|
|
1085
|
+
// through as conditionally rendered when its words appear in the component's view; the runtime
|
|
1086
|
+
// can read only the view function's own source. A component module (one that sets `X.intent` or
|
|
1087
|
+
// `X.uses`) gets, in dev, a tail registering for each such component the words of its string
|
|
1088
|
+
// literals and those of the relative modules it imports, where view helpers live
|
|
1089
|
+
// (globalThis.__SYGNAL_VIEW_TOKENS__, a WeakMap read by checks/dom.ts).
|
|
1090
|
+
const COMPONENT_WITH_SELECTORS_RE = /(?:^|[^\w$.])([A-Z][\w$]*)\.(?:intent|uses)\s*=(?!=)/g;
|
|
1091
|
+
const STRING_RE = /(['"])((?:\\.|(?!\1)[^\\\n])*)\1|`((?:\\[\s\S]|[^\\`])*)`/g;
|
|
1092
|
+
const RELATIVE_IMPORT_RE = /(?:\bfrom|\bimport)\s*\(?\s*(['"])(\.{1,2}\/[^'"]+)\1/g;
|
|
1093
|
+
// A string that is itself a selector ('.save', '#id', 'form.ask', '[data-x]') or a path / URL: its
|
|
1094
|
+
// words aren't markup (the intent's own DOM.click('.svae') would otherwise vouch for its typo)
|
|
1095
|
+
const NOT_MARKUP_RE = /(?:^|[\s>+~,(])[\w-]*[.#[][\w-]|^\s*(?:\/|[\w+-]+:\/\/)/;
|
|
1096
|
+
/** the class / id / tag-like words in a module's string and template literals (comments skipped) */
|
|
1097
|
+
function stringWords(code, into) {
|
|
1098
|
+
for (const m of blankOut(code, false).matchAll(STRING_RE)) {
|
|
1099
|
+
const text = m[2] ?? m[3] ?? '';
|
|
1100
|
+
if (NOT_MARKUP_RE.test(text))
|
|
1101
|
+
continue;
|
|
1102
|
+
for (const w of text.match(/[A-Za-z_][\w-]*/g) || [])
|
|
1103
|
+
into.add(w);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
function viewTokensTail(ctx, code, id) {
|
|
1107
|
+
const file = cleanId(id);
|
|
1108
|
+
if (!/\.[jt]sx?$/.test(file) || id.includes('node_modules') || id.startsWith('\0'))
|
|
1109
|
+
return null;
|
|
1110
|
+
const names = new Set();
|
|
1111
|
+
for (const m of blankOut(code, true).matchAll(COMPONENT_WITH_SELECTORS_RE))
|
|
1112
|
+
names.add(m[1]);
|
|
1113
|
+
if (!names.size)
|
|
1114
|
+
return null;
|
|
1115
|
+
const words = new Set();
|
|
1116
|
+
stringWords(code, words);
|
|
1117
|
+
const specs = new Set(Array.from(blankOut(code, false).matchAll(RELATIVE_IMPORT_RE), m => m[2]));
|
|
1118
|
+
return Promise.all([...specs].map(async (spec) => {
|
|
1119
|
+
try {
|
|
1120
|
+
const r = await ctx.resolve(spec, id);
|
|
1121
|
+
const dep = r && !r.external && cleanId(r.id);
|
|
1122
|
+
if (!dep || !/\.[cm]?[jt]sx?$/.test(dep) || dep.includes('node_modules'))
|
|
1123
|
+
return;
|
|
1124
|
+
ctx.addWatchFile?.(dep);
|
|
1125
|
+
stringWords(await fs.promises.readFile(dep, 'utf8'), words);
|
|
1126
|
+
}
|
|
1127
|
+
catch (_) { /* unreadable: its words are just not added */ }
|
|
1128
|
+
})).then(() => {
|
|
1129
|
+
const comps = [...names].map(n => `typeof ${n} == 'function' && ${n}`).join(', ');
|
|
1130
|
+
return `\n;(() => { try { const m = globalThis.__SYGNAL_VIEW_TOKENS__ ||= new WeakMap(), t = ${JSON.stringify([...words].join(' '))}; for (const c of [${comps}]) if (c) m.set(c, t) } catch (_) {} })();\n`;
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1067
1133
|
// PLAN-5 W-2 (D209): the adapter entries and the optional peer dependencies each one imports
|
|
1068
1134
|
// (the Zag packages pinned together: they depend on each other's exact versions)
|
|
1069
1135
|
const ZAG = '~1.45.0';
|