@colixsystems/widget-sdk 0.188.0 → 0.189.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/src/dev-shims.js CHANGED
@@ -19,6 +19,8 @@
19
19
  // runtime-enumerates the host's namespace). Imports of these packages from a
20
20
  // sibling .jsx file return `422` from the dev server with a clear message.
21
21
 
22
+ import { CONTRACT } from "./contract.js";
23
+
22
24
  // React named exports the Studio re-exposes through the shim. Mirrors the
23
25
  // browser's `react` named-export surface. Adding a new hook in a React minor
24
26
  // release means appending it here.
@@ -61,81 +63,16 @@ export const REACT_NAMED_EXPORTS = [
61
63
  // React's automatic JSX runtime: jsx / jsxs / Fragment, plus the dev variant.
62
64
  export const REACT_JSX_RUNTIME_EXPORTS = ["jsx", "jsxs", "Fragment", "jsxDEV"];
63
65
 
64
- // REQ-WSDK-PLATFORM bundle (sc-1064): the canonical list of bare specifiers the
65
- // runtime web host RESOLVES for a loaded widget — i.e. the ones the Studio's
66
- // `widgetLoader.buildShims()` re-exports from `globalThis.__appstudioWidgetHost__`
67
- // rather than letting a bundle inline a second copy. The web-entry bundler
68
- // (`webbundle.bundleWebEntry`, used by both the publish packer and the dev
69
- // server) marks EXACTLY these `external`, so everything else the entry imports
70
- // (`react-leaflet`, `leaflet`, CSS, PNG assets, …) gets inlined.
71
- //
72
- // This is the SINGLE source of truth (CLAUDE.md §3). It MUST stay in lockstep
73
- // with the frontend's `widgetLoader._hostVettedModules()` + the core React/SDK
74
- // shims it builds. Two backstops enforce the equality: (1) this list's
75
- // contents are pinned by the SDK-side importable test
76
- // (`packages/widget-sdk/src/__tests__/host-externals.test.js`), and (2) the
77
- // loader's own module-load guard in `frontend/src/services/widgetLoader.js`
78
- // throws at import time if `hostShimmedSpecifiers()` drifts from
79
- // `hostExternalSpecifiers()` — the loader's shimmed set can't be asserted from
80
- // a Node test (it imports `react-dom` etc.), so that equality is enforced by
81
- // the load-time guard rather than a separate frontend test.
82
- //
83
- // Why each entry is host-resolved (NOT bundled):
84
- // * `react`, `react/jsx-runtime`, `react/jsx-dev-runtime` — the widget MUST
85
- // share the host's ONE React instance (hooks + context); a bundled second
86
- // React breaks both.
87
- // * `react-dom`, `react-dom/client` — `react-leaflet`'s Popup/Pane render
88
- // through `createPortal` from `react-dom`. A bundled second react-dom
89
- // paired with the host's external React is a mismatched renderer and
90
- // crashes. The Studio is a React-DOM app, so it shims its own react-dom.
91
- // On React 19 the two specifiers expose DIFFERENT surfaces — createPortal /
92
- // flushSync / version live on `react-dom`, createRoot / hydrateRoot on
93
- // `react-dom/client` — so the loader stashes + shims each from its own real
94
- // host namespace (sc-1064).
95
- // * `@colixsystems/widget-sdk` — the widget must route hooks through the SAME
96
- // SDK instance the host built (datastore/theme/navigation live there).
97
- // * `lucide-react-native`, `react-native-svg`, `date-fns`,
98
- // `react-native-qrcode-svg` — vetted packages the host already bundles +
99
- // shims (`_hostVettedModules`); sharing the host copy keeps icons/SVG on
100
- // the host's react-native-web instance. qrcode-svg draws through
101
- // react-native-svg, so externalising it keeps the QR on that same
102
- // instance instead of a bundle inlining a second one (sc-6105).
103
- const HOST_EXTERNAL_SPECIFIERS = [
104
- "react",
105
- "react/jsx-runtime",
106
- "react/jsx-dev-runtime",
107
- "react-dom",
108
- "react-dom/client",
109
- "@colixsystems/widget-sdk",
110
- "lucide-react-native",
111
- "react-native-svg",
112
- "date-fns",
113
- "react-native-qrcode-svg",
114
- // sc-1265: a bundled widget (and any vetted RN package it inlines, e.g.
115
- // react-native-gesture-handler) imports `react-native`; the host resolves it
116
- // to its OWN single react-native-web instance through a blob shim, so the
117
- // bundle shares one RN-web (StyleSheet/context) instead of inlining a second
118
- // copy. On native, Metro resolves the real react-native in the export.
119
- "react-native",
120
- // sc-7191: the vetted pure-JS maths set. Externalised for the same reason as
121
- // date-fns — an AI-agent widget is transpiled, never bundled, so the host
122
- // must resolve the bare import at runtime.
123
- "decimal.js",
124
- "d3-scale",
125
- "d3-shape",
126
- "d3-array",
127
- "simple-statistics",
128
- ];
129
-
130
66
  /**
131
67
  * The canonical "host-resolved at runtime" bare-specifier set — the externals
132
- * the web-entry bundler must NOT inline. Returns a fresh array each call so a
133
- * caller can't mutate the source of truth.
68
+ * the web-entry bundler must NOT inline. Sourced from
69
+ * `CONTRACT.hostExternalSpecifiers`, which documents each entry. Returns a
70
+ * fresh array each call so a caller can't mutate the source of truth.
134
71
  *
135
72
  * @returns {string[]}
136
73
  */
137
74
  export function hostExternalSpecifiers() {
138
- return [...HOST_EXTERNAL_SPECIFIERS];
75
+ return [...CONTRACT.hostExternalSpecifiers];
139
76
  }
140
77
 
141
78
  function reactShimSrc() {