smbls 3.14.857 → 3.14.859

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 (72) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +88 -4
  3. package/core.js +2 -1
  4. package/dist/smbls.cjs +46 -46
  5. package/dist/smbls.cjs.map +3 -3
  6. package/dist/smbls.core.analyze-VTXSSOLD.esm.js +2 -0
  7. package/dist/{smbls.core.analyze-PPLS2PAN.esm.js.map → smbls.core.analyze-VTXSSOLD.esm.js.map} +1 -1
  8. package/dist/smbls.core.chunk-42M5X5D2.esm.js +7 -0
  9. package/dist/smbls.core.chunk-42M5X5D2.esm.js.map +6 -0
  10. package/dist/smbls.core.chunk-DEXTYS42.esm.js +11 -0
  11. package/dist/smbls.core.chunk-DEXTYS42.esm.js.map +1 -0
  12. package/dist/smbls.core.chunk-GBKTEN3N.esm.js +2 -0
  13. package/dist/smbls.core.chunk-GBKTEN3N.esm.js.map +6 -0
  14. package/dist/smbls.core.chunk-KEKRID6S.esm.js +2 -0
  15. package/dist/smbls.core.chunk-KEKRID6S.esm.js.map +6 -0
  16. package/dist/smbls.core.chunk-NY3AS6M5.esm.js +27 -0
  17. package/dist/smbls.core.chunk-NY3AS6M5.esm.js.map +1 -0
  18. package/dist/smbls.core.chunk-OVVEF7PJ.esm.js +36 -0
  19. package/dist/smbls.core.chunk-OVVEF7PJ.esm.js.map +1 -0
  20. package/dist/smbls.core.chunk-XCEZBJ7G.esm.js +22 -0
  21. package/dist/smbls.core.chunk-XCEZBJ7G.esm.js.map +6 -0
  22. package/dist/smbls.core.chunk-Y2TIBI2V.esm.js +2 -0
  23. package/dist/smbls.core.chunk-Y2TIBI2V.esm.js.map +1 -0
  24. package/dist/{smbls.core.dropdown-ZXDSXWKQ.esm.js → smbls.core.dropdown-BLPDXVXL.esm.js} +2 -2
  25. package/dist/{smbls.core.dropdown-ZXDSXWKQ.esm.js.map → smbls.core.dropdown-BLPDXVXL.esm.js.map} +1 -1
  26. package/dist/smbls.core.esm.js +1 -1
  27. package/dist/smbls.core.fetch-IJAKF526.esm.js +2 -0
  28. package/dist/smbls.core.fetch-IJAKF526.esm.js.map +1 -0
  29. package/dist/{smbls.core.fetchOnCreate-IYA76D26.esm.js → smbls.core.fetchOnCreate-C37HV2DR.esm.js} +2 -2
  30. package/dist/smbls.core.inspect-G6OWAZKH.esm.js +8 -0
  31. package/dist/{smbls.core.inspect-ADIDT7QG.esm.js.map → smbls.core.inspect-G6OWAZKH.esm.js.map} +1 -1
  32. package/dist/smbls.core.lazyParts-JFHW4EW6.esm.js +2 -0
  33. package/dist/smbls.core.lazyParts-JFHW4EW6.esm.js.map +6 -0
  34. package/dist/smbls.core.sync-5FCWPNZT.esm.js +2 -0
  35. package/dist/smbls.core.sync-5FCWPNZT.esm.js.map +6 -0
  36. package/dist/smbls.core.windows-KJFEF2HI.esm.js +2 -0
  37. package/dist/{smbls.core.windows-5KS5J3M3.esm.js.map → smbls.core.windows-KJFEF2HI.esm.js.map} +1 -1
  38. package/dist/smbls.embed.iife.js +1 -1
  39. package/dist/smbls.embed.iife.js.map +1 -1
  40. package/dist/smbls.esm.js +46 -46
  41. package/dist/smbls.esm.js.map +1 -1
  42. package/dist/smbls.iife-string.js +2 -2
  43. package/dist/smbls.iife.js +1 -1
  44. package/dist/smbls.iife.js.map +1 -1
  45. package/dist/smbls.server-utils.esm.js +9 -9
  46. package/dist/smbls.server-utils.esm.js.map +3 -3
  47. package/dist/smbls.socket-io-client.esm.js.map +1 -1
  48. package/dist/smbls.tree-shake.json +154 -0
  49. package/index.js +17 -3
  50. package/package.json +7 -7
  51. package/dist/smbls.core.analyze-PPLS2PAN.esm.js +0 -2
  52. package/dist/smbls.core.chunk-2ZCRFEWG.esm.js +0 -36
  53. package/dist/smbls.core.chunk-2ZCRFEWG.esm.js.map +0 -1
  54. package/dist/smbls.core.chunk-BH7NPZAA.esm.js +0 -7
  55. package/dist/smbls.core.chunk-BH7NPZAA.esm.js.map +0 -6
  56. package/dist/smbls.core.chunk-I5EGBLTJ.esm.js +0 -2
  57. package/dist/smbls.core.chunk-I5EGBLTJ.esm.js.map +0 -6
  58. package/dist/smbls.core.chunk-MMC3VKQX.esm.js +0 -2
  59. package/dist/smbls.core.chunk-MMC3VKQX.esm.js.map +0 -1
  60. package/dist/smbls.core.chunk-PDZOHW5Y.esm.js +0 -2
  61. package/dist/smbls.core.chunk-PDZOHW5Y.esm.js.map +0 -6
  62. package/dist/smbls.core.chunk-TG2NZ6VH.esm.js +0 -36
  63. package/dist/smbls.core.chunk-TG2NZ6VH.esm.js.map +0 -1
  64. package/dist/smbls.core.chunk-VG333WGF.esm.js +0 -22
  65. package/dist/smbls.core.chunk-VG333WGF.esm.js.map +0 -6
  66. package/dist/smbls.core.fetch-YW5A5WYS.esm.js +0 -2
  67. package/dist/smbls.core.fetch-YW5A5WYS.esm.js.map +0 -1
  68. package/dist/smbls.core.inspect-ADIDT7QG.esm.js +0 -8
  69. package/dist/smbls.core.sync-CDWW7LM4.esm.js +0 -2
  70. package/dist/smbls.core.sync-CDWW7LM4.esm.js.map +0 -6
  71. package/dist/smbls.core.windows-5KS5J3M3.esm.js +0 -2
  72. /package/dist/{smbls.core.fetchOnCreate-IYA76D26.esm.js.map → smbls.core.fetchOnCreate-C37HV2DR.esm.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,61 @@
1
1
  # smbls
2
2
 
3
+ ## 3.14.859
4
+
5
+ ### Patch Changes
6
+
7
+ - 3aa9e6a: `@symbo.ls/sdk` on demand. A page whose code reads the SDK only through `await import('@symbo.ls/sdk')` gets no SDK bytes in its first document; the SDK loads on the first call, one instance per page, the same build the page would have inlined.
8
+
9
+ frank: a literal `import('<host-registered package>')` in code (never a comment, a string or a member call `x.import(…)`) is emitted as the lazy marker `@symbo.ls/utils` `lazyHostImportExpr(spec)` — registry first, else the page loader `globalThis[Symbol.for('smbls.importHostPackage')]`, else a named rejection `SMBLS_HOST_PACKAGE_NO_LOADER`. Before, frank emitted the `import()` verbatim: a bare private specifier that rejects in the browser. The static tier (`import { X } from '@symbo.ls/sdk'`) is unchanged.
10
+
11
+ utils: `hostPackages.js` holds the shared contract — the marker forms (a stability contract: forms are added, never edited), `classifyHostPackageReads(text, spec, range)` (`none` / `lazy` / `static`; every exact marker is set aside, any other mention is static, so a page inlines in every case it did before), `hostPackageSourcesTag` (the `window.__SMBLS_HOST_SOURCES__` declaration a lazy page carries) and `runtimeProvidesHostPackageLoader` (a page goes lazy only under an smbls runtime that installs the loader).
12
+
13
+ smbls: the host tier moves to `src/hostPackages.js` (re-exported by `frameworkRegistry.js`). New `importHostPackage(spec)` (also `Smbls.importHostPackage`), installed by the full entry as `globalThis[Symbol.for('smbls.importHostPackage')]`: one classic script per package from the page's declaration, with SRI; concurrent calls share one load; registers the global first-wins; named, retryable rejections (`LOAD_FAILED`, `TIMEOUT`, `NO_GLOBAL`) remove the failed script so a retry loads again. `smbls/core` installs nothing.
14
+
15
+ runner (`smbls start` / `smbls build`): a lazy payload gets the declaration instead of the inlined SDK, and the runner serves the SDK file at `/__smbls/host/sdk.<sha256-16>.js` (immutable; any other file under `/__smbls/host/` is a 404); `smbls build` writes it beside `index.html`. Static and SDK-free payloads are byte-identical to before.
16
+
17
+ - b0240a2: The host-package tier leaves a build whose source reads no host-registered package. `smbls build` with `build.treeShakeFeatures` now has the optional feature `hostPackages`: the full entry's on-demand loader (`importHostPackage`) and the shared contract of `@symbo.ls/utils` `hostPackages.js` (the lazy marker forms, the error codes, `classifyHostPackageReads`, `lazyHostImportExpr`, the declaration writer, the asset path). Every utils export is `context.utils`, so a `smbls/core` app that never reads `@symbo.ls/sdk` carried all of it.
18
+
19
+ The CLI keeps the feature when any file its scan reaches reads `@symbo.ls/sdk`: the scan runs `classifyHostPackageReads` (frank's rule) over each file, and a static import, an `import()`, a lazy marker or any other mention counts. It also keeps the feature when the source names an export of the tier, or `keep` lists `hostPackages`. A dropped build keeps the names: each function reports the feature once and returns nothing, the two predicates answer `false`, and the marker forms and error codes are `null`. The full entry still installs the loader, and each call rejects with `SMBLS_HOST_PACKAGE_NO_LOADER` and a message that names the option. Node, the page runtimes, frank and the IIFE never set the flag, so nothing changes there.
20
+
21
+ - e8eaf28: Framework parts that only `context.lazy` groups use leave the main bundle. `smbls build` with `build.treeShakeFeatures` and `"smblsEntry": "core"` scans the main code and each group's own code apart (comments aside). When only group code uses `inertOutside`, the bridge hooks (`onBridgeMount`) or `TooltipLayer`, the build moves them into one small file (`smbls.core.lazyParts-*.js`). smbls loads this file together with the first group load and installs the parts before the group merges, whether that load comes before or after the first render. A part the main code uses, or one `keep` names, stays in the main bundle with no extra request. A group whose entry file the build cannot name keeps every part in the main bundle. XMA: main bundle −2,495 B Brotli; the admin load gets one more request (4.2 KB Brotli).
22
+ - f8d78c4: A lazy route can be built ahead as its group's real page (XMA question 6).
23
+ symbols.json `brender.lazyGroups: 'load' | ['group', …]` makes the build's
24
+ first navigation load the group and render the route as the group's page
25
+ (the group's `when` is asked at build time; false builds the placeholder).
26
+ The page names the groups it was built with (`<meta name="brender-lazy">`)
27
+ and `smbls build` preloads each group's chunk (`<link rel="modulepreload">`
28
+ after the page's own preloads, found through the chunk's source map;
29
+ `build.modulePreload: "strict"` fails the build without one). In the browser
30
+ the boot reads the tag into the new `context.lazyFirstView` (router): the
31
+ first navigation loads those groups and renders their pages, so the takeover
32
+ adopts the built page instead of mounting the placeholder over it. Public
33
+ pages can move out of the main bundle and still arrive built.
34
+
35
+ The default build (no `brender.lazyGroups`) is fixed the same way: a route
36
+ whose group loaded during the render (a context that declares `lazy`, e.g.
37
+ through `brender.context`) already showed the group's page, but the page
38
+ named no group, so the browser mounted the placeholder over it (1 adoption
39
+ miss; on a slow run the built page was removed and rendered again). The
40
+ router now records a first navigation that showed the placeholder and then
41
+ the group's page; the page names that group and preloads its chunk. The
42
+ built content does not change.
43
+
44
+ - b11e6c6: `polyglot.defaultLang` may be a function `(polyglot) => code`, called each time the default is asked (utils `polyglotDefaultLang`; every reader of the default goes through `polyglotFallbackLang`). The `fetch.early` pre-boot script carries its source and calls it before it decides. The language the pre-boot `startLang(ctx)` hook chose for a page load is recorded by the script (utils `polyglotEarlyStartLang`) and is the start language in every `addressLang` mode: under `'strict'` an unprefixed page started in the static default and asked for its labels a second time. A visitor's own stored choice still never wins under `'strict'`; an admin whose hook returns `null` keeps its own rule.
45
+ - 6ecdb94: `afterFirstView` create option (config.js / context.js / `create(App, { afterFirstView })`): `(app, state, context)` runs once per app, a task after the first view is in — after `create()` rendered it or adopted the pre-rendered page, after the first navigation settled — the moment fetch.early's `afterFirstView` hook has. An app no longer polls `window.__BRENDER_HYDRATION__` to learn that a built page was taken over. A hook that throws or rejects is reported, never rethrown. brender switches it off for its server renders.
46
+ - a529b80: Server render and page replace (W7): `el.context.ssr` is true while a component renders in a server render, so app code can tell it runs there. smbls replaces a pre-rendered page in short tasks and swaps it in at once; an adoption that throws falls back to the one-task replace. brender exports its page-weight trims (text between sprite symbols no longer stops the sprite trim) and `stylesheetRules`, which turns a stored stylesheet text back into its rules. `smbls build`: each pre-rendered route carries its own icons after its content (Fix B), and the cli reads brender's page trims as optional exports, so an older brender still builds.
47
+ - d42696c: frank: `workers/<name>.js` is a discovered folder of module Web Workers. `toJSON` ships each worker bundled (esbuild, one ES module, imports inlined) in a `workers` section (`{ <name>: { type: 'module', file, code } }`); a `new URL('<file>', import.meta.url)` inside the worker graph (a `.wasm` beside its glue) resolves through `resolveAssetUrl` (push uploads, `'dataurl'` inlines). `toFS` writes a worker back only where the tree lacks it. The app starts a worker with the bundler-native `new Worker(new URL('../workers/<name>.js', import.meta.url), { type: 'module' })`. frank-audit: `workers/` is a frank slot (no FA006) and FA409 allows `self.X` / `globalThis.X` writes in a worker file (`window` stays banned); FA701 documents head-metadata defaults.
48
+
49
+ helmet: the runtime head never writes a label's stand-in (a polyglot key whose language is still loading, `@symbo.ls/utils` `evaluateText`) — the tag keeps its value until the label lands — and on a head the build wrote (`<meta name="brender">` / `brender-stamp`), on its served path, the app root's metadata does not replace a tag the document carries until the app's values change (a language switch) or the reader navigates. Measured on dev.xma.info (3.14.856): the served title flipped to the app.js default, then to raw `ui.meta.*` keys, before the page's labelled title.
50
+
51
+ Platform half: `@symbo.ls/utils` `SMBLS_PATH_PREFIX` / `workerScriptPath` / `workerNameFromPath` are the one path contract. frank points every published caller's `new URL('…/workers/<name>.js', import.meta.url)` at `new URL('/__smbls/workers/<name>.js', globalThis.location.href)`. mermaid `resolveSmblsRequest` serves `data.workers.<name>.code` there (`text/javascript`, `no-cache` + ETag, `nosniff`), and its boot script no longer inlines `data.workers`.
52
+
53
+ ## 3.14.858
54
+
55
+ ### Patch Changes
56
+
57
+ - 1cd3348: `smbls build` with `build.treeShakeFeatures` and `"smblsEntry": "core"` leaves out the smbls/core kits the configuration never switches on (`windows`, `dropdown`, `tooltip` set `false`; `shorthand`, `analyze`, `inspect` unset; no `editor`; no `'local'` fetch adapter): no file for them in the output (XMA: 16 fewer files, −81 KB js, −662 KB maps). A kit stays when the configuration uses it, when `keep` names it, or when the configuration cannot be read. New optional feature `capsize`: dropped when nothing gives a font metrics (no `useCapsize`/`metrics` key, no `fontFamily` set to a font of its table). With `build.treeShakeLibraries` the boot no longer carries `@symbo.ls/channels`; with `liveSync` dropped it no longer carries the sync applier's page tests. `build.treeShakeIcons` drops a default icon that the project's own design system replaces under the same name.
58
+
3
59
  ## 3.14.857
4
60
 
5
61
  ### Patch Changes
package/README.md CHANGED
@@ -175,9 +175,23 @@ When things happen:
175
175
  node whose element is not built yet is held and dispatched again, once, on
176
176
  the same node when the adoption is done (an element already adopted handles
177
177
  its own events at once); input during the adoption does not close the
178
- window. `firstRender: false` adopts in one task, as before; a page that
179
- replaces the server markup (no registry, `hydrate: false`) renders in one
180
- task; a server render keeps the whole boot in one task.
178
+ window. `firstRender: false` adopts in one task, as before.
179
+ - A boot that REPLACES the server markup (no registry, `hydrate: false`, a
180
+ platform pre-render) builds in the same short tasks: the app is built
181
+ outside the document while the server's page stays on screen with its
182
+ styles, and the server's markup and styles go in the task that inserts the
183
+ app — one page or the other on screen, never both, never neither.
184
+ `window.__BRENDER_HYDRATION__` is `{ replaced: true }` before the app's
185
+ first hook runs, in tasks as in one task: code that tells an adoption from
186
+ a fresh build (`el.context.prerendered` and no flag yet) reads a fresh
187
+ build in every hook. The first page's hooks and `onRouteChanged` run in the
188
+ task that inserts the app, so a hook there that reads layout (`focus()`,
189
+ `getBoundingClientRect()`) makes the new page's first style and layout part
190
+ of that task; read layout after the first frame or in `afterFirstView`.
191
+ `progressive: true` does not apply to a replace; `firstRender: false`
192
+ replaces in one task, and so does the fallback of an adoption that throws
193
+ (it has taken back the server nodes it had claimed). A server render keeps
194
+ the whole boot in one task.
181
195
  - A pre-rendered page shows the data of its build (`smbls build` pages: until
182
196
  the next build). `el.context.prerender` is the build it comes from,
183
197
  `{ stamp, time }` (`<meta name="brender-stamp">`). When the page is flagged
@@ -193,6 +207,28 @@ When things happen:
193
207
  nothing extra. See `@symbo.ls/fetch`, "A pre-built page shows
194
208
  the data of its build".
195
209
 
210
+ ### When the first view is in (`afterFirstView`)
211
+
212
+ Work that must not compete with the first view — an analytics beacon, a page
213
+ view, warming the next route — goes in the `afterFirstView` create option
214
+ (config.js, context.js, or `create(App, { afterFirstView })`):
215
+
216
+ ```js
217
+ // config.js
218
+ export default {
219
+ afterFirstView: (app, state, context) => { app.call('pageView') }
220
+ }
221
+ ```
222
+
223
+ It runs once per app, a task after the first view is in: after `create()`
224
+ rendered it — on a pre-rendered page, after the adoption — and after the
225
+ first navigation settled (a route behind an awaited guard renders later). It
226
+ is the moment fetch.early's own `afterFirstView` hook runs, so an app needs
227
+ no poll on `window.__BRENDER_HYDRATION__` to learn that a built page was
228
+ taken over. Called as the root's `onCreate` is, `(app, state, context)`; a
229
+ hook that throws (or rejects) is reported, never rethrown. A server render
230
+ (brender) never runs it.
231
+
196
232
  ## Plugins
197
233
 
198
234
  domql supports a plugin system via `context.plugins`. Plugins hook into the element lifecycle and can extend how event handlers, props, and metadata are processed.
@@ -273,7 +309,7 @@ Also includes `@symbo.ls/cli`, `@symbo.ls/fetch`, `@symbo.ls/sync`, and `@symbo.
273
309
  | Import | File | What it is |
274
310
  |--------|------|------------|
275
311
  | `smbls` | `dist/smbls.esm.js` (+ `smbls.cjs`) | The full runtime: the public API **plus the platform registry** — every bundled package registered on `globalThis.__SMBLS_PKGS__` so published or fetched project code (frank-serialized functions, `smbls fetch --scope libs` libraries, raw JSON handed to `create()`) resolves its imports. One file. |
276
- | `smbls/core` | `dist/smbls.core.esm.js` + chunks | The same public API **without the registry** (no `registerHostPackages` / `HOST_REGISTERED_PACKAGES`), no Simone client, no socket.io. Code-split: each kit and platform plugin is its own file, downloaded only when the app's configuration switches it on. |
312
+ | `smbls/core` | `dist/smbls.core.esm.js` + chunks | The same public API **without the registry** (no `registerHostPackages` / `HOST_REGISTERED_PACKAGES` / `importHostPackage`, and no on-demand host-package loader), no Simone client, no socket.io. Code-split: each kit and platform plugin is its own file, downloaded only when the app's configuration switches it on. |
277
313
  | `smbls/iife` | `dist/smbls.iife.js` | The full runtime as one script (`window.Smbls`) — what the platform serves. |
278
314
 
279
315
  Use `smbls/core` for an app that runs **no** published or fetched project code — that code reads the registry and gets `{}` without it. Select it for **every** importer of `smbls` at once (a bundler alias), never by importing both entries: they are two bundles, so two copies of the runtime. With the Symbols CLI and parcel, set `"smblsEntry": "core"` in `symbols.json`. With vite: `resolve: { alias: [{ find: /^smbls$/, replacement: 'smbls/core' }] }`.
@@ -294,6 +330,54 @@ In `smbls/core` an app that keeps a kit on pays one module request at boot: the
294
330
 
295
331
  Every dist bundle has a source map next to it (`<file>.map`, sources included). The embed's map is not linked from the file, to keep the embed's byte budget.
296
332
 
333
+ ## Host packages: the platform SDK
334
+
335
+ `@symbo.ls/sdk` is a **host-registered package**: `smbls` (public on npm) never bundles it and no public CDN serves it — the page that runs the code supplies it. Project code reads it in one of two ways.
336
+
337
+ **Static** — `import { SDK } from '@symbo.ls/sdk'` at the top of a file. frank emits a synchronous read of `globalThis.__SMBLS_PKGS__['@symbo.ls/sdk']` with a named error on a miss, and the page runtime inlines the SDK and registers it before boot:
338
+
339
+ ```js
340
+ Smbls.registerHostPackages({ '@symbo.ls/sdk': sdkNamespace }) // before Smbls.create(...)
341
+ ```
342
+
343
+ **On demand** — a literal `import('@symbo.ls/sdk')` inside the function that needs it:
344
+
345
+ ```js
346
+ export const openAccount = async function () {
347
+ const { SDK } = await import('@symbo.ls/sdk')
348
+ const sdk = new SDK({ apiUrl })
349
+ // …
350
+ }
351
+ ```
352
+
353
+ frank rewrites that call into a fixed marker expression (`@symbo.ls/utils` `lazyHostImportExpr`). The page runtimes recognise the marker (`classifyHostPackageReads`): when **every** mention of the SDK in the boot payload is a marker, the first document carries no SDK bytes, only a small declaration of a same-origin, content-hashed, immutable file:
354
+
355
+ ```js
356
+ window.__SMBLS_HOST_SOURCES__ = {
357
+ '@symbo.ls/sdk': { src: '/__smbls/host/sdk.<sha256-16hex>.js', integrity: 'sha384-…', global: 'SymbolsSDK' }
358
+ }
359
+ ```
360
+
361
+ On the first call the marker reads the registry, then asks `importHostPackage` (the full entry installs it as `globalThis[Symbol.for('smbls.importHostPackage')]`; hand-written code can call `Smbls.importHostPackage('@symbo.ls/sdk')`). The loader inserts one `<script>` for the declared file, registers the namespace, and resolves it. The semantics are the inline's: one SDK instance per page (registry first, one shared load, additive registration), the same SDK build the page would have inlined.
362
+
363
+ A failure rejects with an `Error` that has `code`, `specifier` and `retryable`. Catch it and offer a retry:
364
+
365
+ | `code` | When | `retryable` |
366
+ |---|---|---|
367
+ | `SMBLS_HOST_PACKAGE_LOAD_FAILED` | the file did not load (the script is removed; a retry inserts a new one) | yes |
368
+ | `SMBLS_HOST_PACKAGE_TIMEOUT` | the file did not load in 30 s | yes |
369
+ | `SMBLS_HOST_PACKAGE_NO_GLOBAL` | the file loaded but defined no global | yes |
370
+ | `SMBLS_HOST_PACKAGE_NO_SOURCE` | the page declares no file and registered nothing — every server render | no |
371
+ | `SMBLS_HOST_PACKAGE_NO_DOM` | no document to load into | no |
372
+ | `SMBLS_HOST_PACKAGE_UNKNOWN` | the specifier is not host-registered | no |
373
+ | `SMBLS_HOST_PACKAGE_NO_LOADER` | no smbls runtime on the page provides the loader | no |
374
+
375
+ Rules for a page that should stay lazy:
376
+
377
+ - Write only the on-demand form; no static `import … from '@symbo.ls/sdk'` anywhere in the page's parts (app, libraries, kits).
378
+ - Name the specifier nowhere else inside a function body — frank publishes body comments and strings as written, and any other mention makes the page inline the SDK (it still works: the marker then answers from the registry).
379
+ - Push with a CLI whose frank has the marker. An older frank publishes the `import()` as written, and a browser cannot resolve that bare private specifier.
380
+
297
381
  ## SEO metadata
298
382
 
299
383
  Define metadata on your app or pages. Values can be static or functions:
package/core.js CHANGED
@@ -14,7 +14,8 @@
14
14
  // kits and platform plugins are separate files loaded only when switched on.
15
15
  //
16
16
  // The export list below is index.js's, minus the registry's own surface
17
- // (`registerHostPackages`, `HOST_REGISTERED_PACKAGES`); it is a copy, not an
17
+ // (`registerHostPackages`, `HOST_REGISTERED_PACKAGES`, `importHostPackage` —
18
+ // and index.js's install of that on-demand loader); it is a copy, not an
18
19
  // import of index.js, which would bring the registry along.
19
20
  // __tests__/coreEntry.test.js keeps the two lists in step, and from source
20
21
  // both entries share every module instance. Never import both PREBUILT