@stacksjs/stx 0.2.119 → 0.2.121

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.
Files changed (62) hide show
  1. package/dist/builtins/attrs.d.ts +16 -0
  2. package/dist/builtins/attrs.js +16 -0
  3. package/dist/builtins/safe-image.js +2 -9
  4. package/dist/builtins/stx-image.js +2 -9
  5. package/dist/builtins/stx-link.js +2 -9
  6. package/dist/cli.js +1869 -863
  7. package/dist/client-script-bundler.d.ts +9 -7
  8. package/dist/client-script-bundler.js +43 -4
  9. package/dist/client-script.d.ts +24 -0
  10. package/dist/client-script.js +59 -5
  11. package/dist/component-library.js +30 -12
  12. package/dist/component-registry.d.ts +1 -0
  13. package/dist/component-renderer.js +13 -5
  14. package/dist/composables/index.d.ts +1 -0
  15. package/dist/composables/index.js +1 -0
  16. package/dist/composables/use-scroll-lock.d.ts +13 -0
  17. package/dist/composables/use-scroll-lock.js +55 -0
  18. package/dist/composition-api.d.ts +1 -1
  19. package/dist/composition-api.js +13 -4
  20. package/dist/craft-bridge.d.ts +80 -1
  21. package/dist/craft-bridge.js +80 -1
  22. package/dist/craft-components.d.ts +77 -3
  23. package/dist/craft-components.js +138 -9
  24. package/dist/craft.js +12708 -118
  25. package/dist/dev-server/crosswind.d.ts +15 -1
  26. package/dist/dev-server/crosswind.js +12 -3
  27. package/dist/dev-server/serve-app.js +3 -3
  28. package/dist/document-shell.d.ts +17 -0
  29. package/dist/document-shell.js +72 -2
  30. package/dist/expressions.js +14 -7
  31. package/dist/head.d.ts +8 -0
  32. package/dist/head.js +11 -8
  33. package/dist/html-masking.d.ts +12 -0
  34. package/dist/html-masking.js +50 -15
  35. package/dist/index.d.ts +9 -1
  36. package/dist/index.js +9 -1
  37. package/dist/native-build.d.ts +6 -0
  38. package/dist/native-build.js +77 -60
  39. package/dist/process.js +11 -3
  40. package/dist/pwa.js +1232 -508
  41. package/dist/render.js +6 -1
  42. package/dist/runtime-globals.d.ts +7 -4
  43. package/dist/runtime-globals.js +10 -2
  44. package/dist/runtime-injection.js +15 -1
  45. package/dist/signal-processing.js +19 -28
  46. package/dist/signals-api.d.ts +2 -0
  47. package/dist/signals-api.js +9 -0
  48. package/dist/signals.js +785 -62
  49. package/dist/ssg.js +1176 -452
  50. package/dist/state-management.d.ts +1 -1
  51. package/dist/state-management.js +1 -1
  52. package/dist/strict-lint.d.ts +1 -1
  53. package/dist/strict-lint.js +1 -1
  54. package/dist/stx.d.ts +6 -0
  55. package/dist/style-scoping.js +10 -0
  56. package/dist/utils.js +5 -3
  57. package/dist/variable-extractor.js +14 -22
  58. package/dist/vue-template.js +3 -2
  59. package/dist/x-element.d.ts +2 -2
  60. package/dist/x-element.js +9 -8
  61. package/package.json +5 -5
  62. package/stx.d.ts +6 -0
package/dist/render.js CHANGED
@@ -120,7 +120,12 @@ ${clientScripts.join(`
120
120
  const contentMatch = fullScript.match(/<script\b[^>]*>([\s\S]*?)<\/script>/);
121
121
  if (!contentMatch)
122
122
  return fullScript;
123
- return await processClientScript(contentMatch[1], { eventBindings, templateContent: output, serverData });
123
+ return await processClientScript(contentMatch[1], {
124
+ eventBindings,
125
+ templateContent: output,
126
+ serverData,
127
+ filePath
128
+ });
124
129
  }))).join(`
125
130
  `);
126
131
  if (output.match(/(<\/body>)/i))
@@ -9,8 +9,11 @@
9
9
  * A local declaration is intentionally allowed to shadow a runtime convenience
10
10
  * global, just as an explicit import would. Omitting it from this destructure
11
11
  * prevents duplicate-binding syntax errors.
12
+ * @param source optionally limits bindings to identifiers referenced by one
13
+ * component script. Page-level callers omit it and retain the full authoring
14
+ * surface.
12
15
  */
13
- export declare function buildRuntimeGlobalsDestructure(declaration?: 'const' | 'var', exclude?: readonly string[]): string;
16
+ export declare function buildRuntimeGlobalsDestructure(declaration?: 'const' | 'var', exclude?: readonly string[], source?: string): string;
14
17
  /**
15
18
  * Runtime Globals
16
19
  *
@@ -26,10 +29,10 @@ export declare function buildRuntimeGlobalsDestructure(declaration?: 'const' | '
26
29
  * script but threw in a page, `onMounted()` resolved in a page but threw in an
27
30
  * `@include`d component. See #1785.
28
31
  *
29
- * Two entries were also phantoms — `inject` and `nextTick` were destructured by
32
+ * Two entries were also phantoms - `inject` and `nextTick` were destructured by
30
33
  * one site but never defined on `window.stx` at all, so they silently evaluated
31
- * to `undefined` and threw "is not a function" when called. They are omitted
32
- * here; re-add them only alongside a real implementation.
34
+ * to `undefined` and threw "is not a function" when called. `nextTick` now has a
35
+ * signals-runtime implementation; `inject` remains omitted until it does too.
33
36
  *
34
37
  * Adding a runtime global is now a one-line change here. `runtime-globals.test.ts`
35
38
  * asserts every name actually exists on `window.stx` and that all three call
@@ -12,6 +12,7 @@ export const STX_RUNTIME_GLOBALS = [
12
12
  "goBack",
13
13
  "goForward",
14
14
  "navigate",
15
+ "nextTick",
15
16
  "onBeforeUnmount",
16
17
  "onDestroy",
17
18
  "onMount",
@@ -34,6 +35,7 @@ export const STX_RUNTIME_GLOBALS = [
34
35
  "useFetch",
35
36
  "useFocus",
36
37
  "useHead",
38
+ "useId",
37
39
  "useInterval",
38
40
  "useLocalStorage",
39
41
  "useMediaQuery",
@@ -47,6 +49,7 @@ export const STX_RUNTIME_GLOBALS = [
47
49
  "useReactiveProp",
48
50
  "useRef",
49
51
  "useRoute",
52
+ "useScrollLock",
50
53
  "useSearchParams",
51
54
  "useSeoMeta",
52
55
  "useSessionStorage",
@@ -59,7 +62,12 @@ export const STX_RUNTIME_GLOBALS = [
59
62
  "watchEffect",
60
63
  "withDefaults"
61
64
  ], COMPONENT_SCOPE_LOCAL_GLOBALS = ["onMount", "onDestroy"];
62
- export function buildRuntimeGlobalsDestructure(declaration = "const", exclude = []) {
63
- const names = exclude.length ? STX_RUNTIME_GLOBALS.filter((name) => !exclude.includes(name)) : STX_RUNTIME_GLOBALS;
65
+ export function buildRuntimeGlobalsDestructure(declaration = "const", exclude = [], source) {
66
+ let names = exclude.length ? STX_RUNTIME_GLOBALS.filter((name) => !exclude.includes(name)) : STX_RUNTIME_GLOBALS;
67
+ if (source !== void 0)
68
+ names = names.filter((name) => {
69
+ const escaped = name.replace(/[$()*+.?[\\\]^{|}-]/g, "\\$&");
70
+ return new RegExp(`(^|[^\\w$])${escaped}(?![\\w$])`).test(source);
71
+ });
64
72
  return `${declaration} { ${names.join(", ")} } = window.stx;`;
65
73
  }
@@ -16,7 +16,21 @@ export function injectBrowserRuntime(template) {
16
16
  "browserQuery",
17
17
  "BrowserQueryBuilder",
18
18
  "configureBrowser",
19
- "createBrowserModel"
19
+ "createBrowserModel",
20
+ "debounce",
21
+ "throttle",
22
+ "retry",
23
+ "sleep",
24
+ "wait",
25
+ "delay",
26
+ "waitUntil",
27
+ "waitWhile",
28
+ "lazy",
29
+ "clamp",
30
+ "rand",
31
+ "readableSize",
32
+ "useDocumentVisibility",
33
+ "useIntervalFn"
20
34
  ].some((sym) => {
21
35
  return new RegExp(`\\b${sym}\\b`).test(clientCode);
22
36
  }), jsBuiltins = new Set(["Promise", "Object", "Array", "Map", "Set", "Date", "Error", "JSON", "Math", "Number", "String", "RegExp", "Symbol", "WeakMap", "WeakSet", "Proxy", "Reflect", "Intl", "URL", "URLSearchParams", "FormData", "Headers", "Request", "Response", "AbortController", "EventTarget", "Element", "Document", "Node", "Window", "Console", "Storage", "Navigator", "Blob", "File", "FileReader", "HTMLElement", "SVGElement", "Event", "CustomEvent", "DOMParser", "XMLSerializer", "WebSocket", "Worker", "SharedWorker", "IntersectionObserver", "MutationObserver", "ResizeObserver", "PerformanceObserver", "Notification", "Bun", "Buffer", "Process"]), modelPattern = /\b([A-Z][a-zA-Z0-9]*)\s*\.\s*(all|find|first|get|where|orderBy|orderByDesc|limit|select|pluck|create|update|delete)\s*\(/g;
@@ -1,43 +1,32 @@
1
- import { generateServerDataBridge } from "./client-script.js";
1
+ import { generateServerDataBridge, injectBrowserCoreAutoImports } from "./client-script.js";
2
2
  import { findIfBlocks } from "./parser/index.js";
3
3
  import { buildRuntimeGlobalsDestructure } from "./runtime-globals.js";
4
4
  import { transformStoreImports } from "./store-imports.js";
5
5
  import { shouldTranspileTypeScript, transpileTypeScript } from "./utils.js";
6
6
  import { injectSignalsRuntime, injectBrowserRuntime } from "./runtime-injection.js";
7
+ import { matchScriptElement, scanAtElementPosition } from "./html-masking.js";
7
8
  let signalSetupCounter = 0;
8
- const TAG_ATTR_RUN = `(?:"[^"]*"|'[^']*'|[^>"'])*`, SCRIPT_OPEN_RE = /<script\b([^>]*)>/gi, SINGLE_ELEMENT_RE = /^<([a-zA-Z][a-zA-Z0-9-]*)\b((?:\s+[^=\s>]+(?:=(?:"[^"]*"|'[^']*'|[^\s>]*))?)*\s*)>([\s\S]*)<\/\1>$/s;
9
+ const TAG_ATTR_RUN = `(?:"[^"]*"|'[^']*'|[^>"'])*`, SINGLE_ELEMENT_RE = /^<([a-zA-Z][a-zA-Z0-9-]*)\b((?:\s+[^=\s>]+(?:=(?:"[^"]*"|'[^']*'|[^\s>]*))?)*\s*)>([\s\S]*)<\/\1>$/s;
9
10
  export function scanScriptTags(html, opts = {}) {
10
11
  const out = [];
11
- let cursor = 0;
12
- while (cursor < html.length) {
13
- SCRIPT_OPEN_RE.lastIndex = cursor;
14
- const m = SCRIPT_OPEN_RE.exec(html);
15
- if (!m)
16
- break;
17
- const commentStart = html.indexOf("<!--", cursor);
18
- if (commentStart !== -1 && commentStart < m.index) {
19
- const commentEnd = html.indexOf("-->", commentStart + 4);
20
- if (commentEnd === -1)
21
- break;
22
- cursor = commentEnd + 3;
23
- continue;
24
- }
25
- const attrs = m[1], bodyStart = m.index + m[0].length, closeIdx = html.toLowerCase().indexOf("</script>", bodyStart);
26
- if (closeIdx === -1)
27
- break;
28
- const end = closeIdx + 9;
29
- if (opts.skipAttrs && opts.skipAttrs.test(attrs)) {
30
- cursor = end;
12
+ for (const item of scanAtElementPosition(html, matchScriptElement)) {
13
+ const opening = item.token.match(/^<script\b([^>]*)>/i), closing = item.token.match(/<\/script\s*>$/i);
14
+ if (!opening || !closing)
31
15
  continue;
16
+ const attrs = opening[1];
17
+ if (opts.skipAttrs) {
18
+ opts.skipAttrs.lastIndex = 0;
19
+ if (opts.skipAttrs.test(attrs))
20
+ continue;
32
21
  }
22
+ const bodyStart = opening[0].length, bodyEnd = item.token.length - closing[0].length;
33
23
  out.push({
34
- fullMatch: html.slice(m.index, end),
24
+ fullMatch: item.token,
35
25
  attrs,
36
- body: html.slice(bodyStart, closeIdx),
37
- start: m.index,
38
- end
26
+ body: item.token.slice(bodyStart, bodyEnd),
27
+ start: item.start,
28
+ end: item.end
39
29
  });
40
- cursor = end;
41
30
  }
42
31
  return out;
43
32
  }
@@ -89,6 +78,7 @@ export function hasSignalsSyntax(template) {
89
78
  /\breactive\s*(?:<[^>]*>)?\s*\(/,
90
79
  /\bwatch\s*(?:<[^>]*>)?\s*\(/,
91
80
  /\bwatchEffect\s*(?:<[^>]*>)?\s*\(/,
81
+ /\buseId\s*\(/,
92
82
  /\buseReactiveProp\s*(?:<[^>]*>)?\s*\(/,
93
83
  /\s:(?:if|else-if|else|for|show|text|html|model)\s*=/,
94
84
  /data-stx(?:-auto)?(?![-\w])/,
@@ -668,7 +658,7 @@ function dedupeTopLevelDeclarations(code) {
668
658
  export async function processScriptSetup(template, filePath, serverData) {
669
659
  const scripts = scanScriptTags(template, {
670
660
  skipAttrs: /\bserver\b|\bsrc\s*=|\bdata-stx-scoped\b|\bdata-stx-router\b/
671
- }), SIGNAL_API_RE = /\b(?:state|derived|effect|ref|reactive|computed|watch|watchEffect|useStore|useLocalStorage|useSessionStorage|useCookie|useReactiveProp|useFetch|useRef|useEventListener|useDebounce|useDebouncedValue|useThrottle|useInterval|useTimeout|useToggle|useCounter|useClickOutside|useFocus|useAsync|useColorMode|useDark|useMediaQuery|usePreferredDark|usePreferredLight|usePreferredReducedMotion|usePreferredContrast|useWebSocket|useRoute|useSearchParams|onMount|onDestroy|defineProps|withDefaults|defineEmits|defineExpose|defineSlots|useOptimistic)\s*(?:<[^>]*>)?\s*\(/, signalScripts = [];
661
+ }), SIGNAL_API_RE = /\b(?:state|derived|effect|ref|reactive|computed|watch|watchEffect|useStore|useLocalStorage|useSessionStorage|useCookie|useId|useReactiveProp|useFetch|useRef|useEventListener|useDebounce|useDebouncedValue|useThrottle|useInterval|useTimeout|useToggle|useCounter|useClickOutside|useFocus|useAsync|useColorMode|useDark|useMediaQuery|useScrollLock|usePreferredDark|usePreferredLight|usePreferredReducedMotion|usePreferredContrast|useWebSocket|useRoute|useSearchParams|onMount|onDestroy|defineProps|withDefaults|defineEmits|defineExpose|defineSlots|useOptimistic)\s*(?:<[^>]*>)?\s*\(/, signalScripts = [];
672
662
  for (const s of scripts) {
673
663
  let content = s.body;
674
664
  if (shouldTranspileTypeScript(s.attrs))
@@ -681,6 +671,7 @@ export async function processScriptSetup(template, filePath, serverData) {
681
671
  const setupFnName = `__stx_setup_${Date.now()}_${signalSetupCounter++}`, { hasUserImports, bundleClientScript } = await import("./client-script-bundler.js"), resolvedParts = [];
682
672
  for (let i = 0;i < signalScripts.length; i++) {
683
673
  let scriptContent = signalScripts[i].content;
674
+ scriptContent = injectBrowserCoreAutoImports(scriptContent).code;
684
675
  if (hasUserImports(scriptContent)) {
685
676
  console.log("[stx:bundler] bundling signal script imports");
686
677
  scriptContent = await bundleClientScript(scriptContent, filePath || "", {
@@ -308,6 +308,7 @@ export declare function useOptimistic<T, A>(base: Signal<T> | DerivedSignal<T> |
308
308
  */
309
309
  export declare interface Signal<T> {
310
310
  (): T
311
+ value: T
311
312
  set(value: T): void
312
313
  update(fn: (current: T) => T): void
313
314
  subscribe(callback: (value: T, prev: T) => void): () => void
@@ -324,6 +325,7 @@ export declare interface Signal<T> {
324
325
  */
325
326
  export declare interface DerivedSignal<T> {
326
327
  (): T
328
+ readonly value: T
327
329
  readonly _isDerived: true
328
330
  }
329
331
  /**
@@ -28,6 +28,11 @@ export function state(initialValue) {
28
28
  return () => subscribers.delete(callback);
29
29
  };
30
30
  Object.defineProperty(signal, "_isSignal", { value: !0, writable: !1 });
31
+ Object.defineProperty(signal, "value", {
32
+ get: () => signal(),
33
+ set: (newValue) => signal.set(newValue),
34
+ configurable: !0
35
+ });
31
36
  return signal;
32
37
  }
33
38
  export function derived(compute) {
@@ -58,6 +63,10 @@ export function derived(compute) {
58
63
  return cachedValue;
59
64
  };
60
65
  Object.defineProperty(signal, "_isDerived", { value: !0, writable: !1 });
66
+ Object.defineProperty(signal, "value", {
67
+ get: () => signal(),
68
+ configurable: !0
69
+ });
61
70
  return signal;
62
71
  }
63
72
  export function effect(fn, options = {}) {