@ggui-ai/iframe-runtime 0.9.0 → 0.10.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.
@@ -39,17 +39,26 @@ export declare const EMPTY_COMPILED_VALIDATOR_SET: CompiledValidatorSet;
39
39
  */
40
40
  export declare function loadCompiledValidators(meta: CompiledContractValidators | undefined, warn?: (message: string, detail: unknown) => void): Promise<CompiledValidatorSet>;
41
41
  /**
42
- * #109 content-addressable variant: fetch the validator-bundle URL,
43
- * dynamic-import the response, then delegate to
44
- * {@link loadCompiledValidators}. Returns {@link EMPTY_COMPILED_VALIDATOR_SET}
42
+ * #109 content-addressable variant: fetch the validator-bundle URL via
43
+ * ONE dynamic import. Returns {@link EMPTY_COMPILED_VALIDATOR_SET}
45
44
  * when `url` is undefined OR the fetch/import fails — sidecar
46
45
  * semantics, the server-side `assertActionContract` gate remains
47
46
  * authoritative on validator absence.
48
47
  *
49
- * Response shape: an ES module whose `default` export is a
50
- * {@link CompiledContractValidators} object (produced server-side by
51
- * `bundleCompiledValidatorsAsModule`). `Cache-Control: immutable` so
52
- * repeat renders with the same contract hit browser cache with no
48
+ * Response shape (v2 executable format, ggui#522 slice 2): an ES
49
+ * module whose `default` export carries the validate FUNCTIONS
50
+ * themselves (produced server-side by
51
+ * `bundleValidatorExprsAsExecutableModule`) — the single https import
52
+ * is the whole load, governed by `script-src` origins alone. No
53
+ * per-validator `blob:` import remains on this path, which is what
54
+ * lets a strict-CSP embedder (no `blob:`, no `data:`, no
55
+ * `'unsafe-eval'`) run client-side outbound validation at all.
56
+ *
57
+ * A default export whose leaves are not functions (the retired v1
58
+ * format carried module SOURCES as strings — reachable only through a
59
+ * stale CDN copy under a pre-salt URL, which no current slice mints)
60
+ * degrades to the empty set with a warning. `Cache-Control: immutable`
61
+ * so repeat renders with the same contract hit browser cache with no
53
62
  * round-trip.
54
63
  */
55
64
  export declare function loadCompiledValidatorsFromUrl(url: string | undefined, warn?: (message: string, detail: unknown) => void): Promise<CompiledValidatorSet>;
@@ -73,17 +73,26 @@ export async function loadCompiledValidators(meta, warn) {
73
73
  };
74
74
  }
75
75
  /**
76
- * #109 content-addressable variant: fetch the validator-bundle URL,
77
- * dynamic-import the response, then delegate to
78
- * {@link loadCompiledValidators}. Returns {@link EMPTY_COMPILED_VALIDATOR_SET}
76
+ * #109 content-addressable variant: fetch the validator-bundle URL via
77
+ * ONE dynamic import. Returns {@link EMPTY_COMPILED_VALIDATOR_SET}
79
78
  * when `url` is undefined OR the fetch/import fails — sidecar
80
79
  * semantics, the server-side `assertActionContract` gate remains
81
80
  * authoritative on validator absence.
82
81
  *
83
- * Response shape: an ES module whose `default` export is a
84
- * {@link CompiledContractValidators} object (produced server-side by
85
- * `bundleCompiledValidatorsAsModule`). `Cache-Control: immutable` so
86
- * repeat renders with the same contract hit browser cache with no
82
+ * Response shape (v2 executable format, ggui#522 slice 2): an ES
83
+ * module whose `default` export carries the validate FUNCTIONS
84
+ * themselves (produced server-side by
85
+ * `bundleValidatorExprsAsExecutableModule`) — the single https import
86
+ * is the whole load, governed by `script-src` origins alone. No
87
+ * per-validator `blob:` import remains on this path, which is what
88
+ * lets a strict-CSP embedder (no `blob:`, no `data:`, no
89
+ * `'unsafe-eval'`) run client-side outbound validation at all.
90
+ *
91
+ * A default export whose leaves are not functions (the retired v1
92
+ * format carried module SOURCES as strings — reachable only through a
93
+ * stale CDN copy under a pre-salt URL, which no current slice mints)
94
+ * degrades to the empty set with a warning. `Cache-Control: immutable`
95
+ * so repeat renders with the same contract hit browser cache with no
87
96
  * round-trip.
88
97
  */
89
98
  export async function loadCompiledValidatorsFromUrl(url, warn) {
@@ -96,7 +105,31 @@ export async function loadCompiledValidatorsFromUrl(url, warn) {
96
105
  warn?.('[ggui:validators] contract bundle: default export is not an object', compiled);
97
106
  return EMPTY_COMPILED_VALIDATOR_SET;
98
107
  }
99
- return loadCompiledValidators(compiled, warn);
108
+ const groups = compiled;
109
+ const pickGroup = (group, kind) => {
110
+ const map = new Map();
111
+ if (group === undefined)
112
+ return map;
113
+ for (const [name, fn] of Object.entries(group)) {
114
+ if (isValidateFunction(fn)) {
115
+ map.set(name, fn);
116
+ }
117
+ else {
118
+ warn?.(`[ggui:validators] ${kind}.${name}: bundle entry is not a function (stale v1-format bundle?)`, typeof fn);
119
+ }
120
+ }
121
+ return map;
122
+ };
123
+ const props = isValidateFunction(groups.props) ? groups.props : undefined;
124
+ if (groups.props !== undefined && props === undefined) {
125
+ warn?.('[ggui:validators] props: bundle entry is not a function (stale v1-format bundle?)', typeof groups.props);
126
+ }
127
+ return {
128
+ ...(props !== undefined ? { props } : {}),
129
+ actions: pickGroup(groups.actions, 'action'),
130
+ streams: pickGroup(groups.streams, 'stream'),
131
+ context: pickGroup(groups.context, 'context'),
132
+ };
100
133
  }
101
134
  catch (err) {
102
135
  warn?.(`[ggui:validators] contract bundle: failed to load ${url}`, err);