smbls 3.14.2 → 3.14.6

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/package.json CHANGED
@@ -1,50 +1,59 @@
1
1
  {
2
2
  "name": "smbls",
3
- "version": "3.14.2",
3
+ "version": "3.14.6",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
- "module": "./index.js",
7
- "main": "./index.js",
6
+ "module": "./dist/smbls.esm.js",
7
+ "main": "./dist/smbls.cjs",
8
+ "unpkg": "./dist/smbls.iife.js",
9
+ "jsdelivr": "./dist/smbls.iife.js",
8
10
  "exports": {
9
- ".": "./index.js",
10
- "./iife": "./dist/iife/index.js",
11
- "./iife-string": "./dist/iife/index-string.js",
12
- "./src/*": "./src/*",
11
+ ".": {
12
+ "development": "./index.js",
13
+ "import": "./dist/smbls.esm.js",
14
+ "require": "./dist/smbls.cjs",
15
+ "default": "./dist/smbls.esm.js"
16
+ },
17
+ "./iife": "./dist/smbls.iife.js",
13
18
  "./package.json": "./package.json"
14
19
  },
15
20
  "source": "index.js",
16
21
  "files": [
17
22
  "dist",
18
- "*.js",
19
- "*.json",
20
- "src"
23
+ "*.md",
24
+ "LICENSE"
21
25
  ],
22
- "dependencies": {
23
- "@symbo.ls/analyze": "^3.14.0",
24
- "@symbo.ls/signal": "^3.14.0",
25
- "@symbo.ls/element": "^3.14.0",
26
- "@symbo.ls/state": "^3.14.0",
27
- "@symbo.ls/css": "^3.14.0",
28
- "@symbo.ls/utils": "^3.14.0",
29
- "@symbo.ls/wasm": "^3.14.0",
30
- "@symbo.ls/capsize": "^3.14.0",
31
- "@symbo.ls/helmet": "^3.14.0",
32
- "@symbo.ls/fetch": "^3.14.0",
33
- "@symbo.ls/polyglot": "^3.14.0",
34
- "@symbo.ls/scratch": "^3.14.0",
35
- "@symbo.ls/shorthand": "^3.14.0",
36
- "@symbo.ls/sync": "^3.14.0",
37
- "@symbo.ls/default-config": "^3.14.0",
38
- "@symbo.ls/router": "^3.14.0",
39
- "attrs-in-props": "^3.14.0",
40
- "css-in-props": "^3.14.0",
41
- "domql": "^3.14.0"
42
- },
43
26
  "scripts": {
44
- "build:esm": "esbuild *.js src/*.js --target=es2020 --format=esm --outdir=dist/esm",
45
- "build:cjs": "esbuild *.js src/*.js --target=node18 --format=cjs --outdir=dist/cjs",
46
- "build:iife": "esbuild index.js --bundle --target=es2020 --format=iife --global-name=Smbls --outfile=dist/iife/index.js --minify && node scripts/build-iife-string.mjs",
47
- "build:browser": "esbuild index.js --bundle --target=es2020 --format=esm --outfile=dist/browser/index.js --minify"
27
+ "build:esm": "node build.mjs esm dist/smbls.esm.js",
28
+ "build:cjs": "node build.mjs cjs dist/smbls.cjs",
29
+ "build:iife": "node build.mjs iife dist/smbls.iife.js",
30
+ "build": "rimraf dist && npm run build:esm && npm run build:cjs && npm run build:iife",
31
+ "prepublishOnly": "npm run build"
32
+ },
33
+ "devDependencies": {
34
+ "@symbo.ls/analyze": "^3.14.4",
35
+ "@symbo.ls/signal": "^3.14.5",
36
+ "@symbo.ls/element": "^3.14.8",
37
+ "@symbo.ls/state": "^3.14.6",
38
+ "@symbo.ls/css": "^3.14.6",
39
+ "@symbo.ls/utils": "^3.14.7",
40
+ "@symbo.ls/wasm": "^3.14.6",
41
+ "@symbo.ls/capsize": "^3.14.4",
42
+ "@symbo.ls/helmet": "^3.14.4",
43
+ "@symbo.ls/inspect": "^3.14.5",
44
+ "@symbo.ls/fetch": "^3.14.4",
45
+ "@symbo.ls/polyglot": "^3.14.4",
46
+ "@symbo.ls/scratch": "^3.14.6",
47
+ "@symbo.ls/shorthand": "^3.14.5",
48
+ "@symbo.ls/sync": "^3.14.6",
49
+ "@symbo.ls/default-config": "^3.14.8",
50
+ "@symbo.ls/router": "^3.14.5",
51
+ "attrs-in-props": "^3.14.3",
52
+ "css-in-props": "^3.14.3",
53
+ "domql": "^3.14.3"
48
54
  },
49
- "sideEffects": false
55
+ "sideEffects": false,
56
+ "publishConfig": {
57
+ "access": "public"
58
+ }
50
59
  }
package/dist/cjs/index.js DELETED
@@ -1,27 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __copyProps = (to, from, except, desc) => {
7
- if (from && typeof from === "object" || typeof from === "function") {
8
- for (let key of __getOwnPropNames(from))
9
- if (!__hasOwnProp.call(to, key) && key !== except)
10
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
- }
12
- return to;
13
- };
14
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
- var index_exports = {};
17
- module.exports = __toCommonJS(index_exports);
18
- __reExport(index_exports, require("@domql/utils"), module.exports);
19
- __reExport(index_exports, require("attrs-in-props"), module.exports);
20
- __reExport(index_exports, require("@symbo.ls/create"), module.exports);
21
- __reExport(index_exports, require("css-in-props"), module.exports);
22
- __reExport(index_exports, require("@symbo.ls/default-config"), module.exports);
23
- __reExport(index_exports, require("@symbo.ls/emotion"), module.exports);
24
- __reExport(index_exports, require("@symbo.ls/init"), module.exports);
25
- __reExport(index_exports, require("@symbo.ls/scratch"), module.exports);
26
- __reExport(index_exports, require("@symbo.ls/uikit"), module.exports);
27
- __reExport(index_exports, require("@symbo.ls/utils"), module.exports);
@@ -1,4 +0,0 @@
1
- {
2
- "type": "commonjs",
3
- "main": "index.js"
4
- }
package/dist/esm/index.js DELETED
@@ -1,10 +0,0 @@
1
- export * from "@domql/utils";
2
- export * from "attrs-in-props";
3
- export * from "@symbo.ls/create";
4
- export * from "css-in-props";
5
- export * from "@symbo.ls/default-config";
6
- export * from "@symbo.ls/emotion";
7
- export * from "@symbo.ls/init";
8
- export * from "@symbo.ls/scratch";
9
- export * from "@symbo.ls/uikit";
10
- export * from "@symbo.ls/utils";
package/index.js DELETED
@@ -1,30 +0,0 @@
1
- 'use strict'
2
-
3
- // v3.14 entry point - re-exports all framework packages
4
-
5
- // Core v3.14 primitives (NEW)
6
- export * from '@symbo.ls/signal'
7
- export * from '@symbo.ls/css'
8
-
9
- // Core framework
10
- export * from '@symbo.ls/utils'
11
- export { update, dispose, remove, REGISTRY, LIFECYCLE_EVENTS, DELEGATED_EVENTS, MIXINS, addDelegatedEvent, removeDelegatedEvent, registerEvent, cacheNode, detectTag, createHTMLNode, isValidTag, isSvgTag, SVG_TAGS, applyExtends, addMethods } from '@symbo.ls/element'
12
- export * from '@symbo.ls/state'
13
-
14
- // Attribute & CSS processing
15
- export * from 'attrs-in-props'
16
- export * from 'css-in-props'
17
-
18
- // Design system & default components
19
- export * from '@symbo.ls/scratch'
20
- export * from '@symbo.ls/default-config'
21
-
22
- // WASM acceleration (lazy-loaded)
23
- // Wire CSS engine hook so WASM auto-accelerates CSS generation when loaded
24
- export { loadWasm, isWasmLoaded, setCssEngineHook } from '@symbo.ls/wasm'
25
- import { setCssEngineHook } from '@symbo.ls/wasm'
26
- import { setWasmEngine } from '@symbo.ls/css'
27
- setCssEngineHook(setWasmEngine)
28
-
29
- // Main create functions
30
- export * from './src/index.js'
@@ -1,362 +0,0 @@
1
- 'use strict'
2
-
3
- import { create as createElement } from '@symbo.ls/element'
4
- import * as uikit from '@symbo.ls/default-config/components'
5
- import { CSS_PROPS_REGISTRY } from 'css-in-props'
6
-
7
- import { isString, isNode, isObject, destringifyGlobalScope, deepDestringifyFunctions, setActiveRootState } from '@symbo.ls/utils'
8
- import { defaultDefine } from './define.js'
9
- import { initRouter } from './router.js'
10
- import { initializeExtend } from './syncExtend.js'
11
-
12
- import {
13
- prepareComponents,
14
- prepareDependencies,
15
- prepareDesignSystem,
16
- prepareWindow,
17
- prepareRequire,
18
- preparePages,
19
- prepareState,
20
- prepareUtils,
21
- prepareMethods,
22
- prepareSharedLibs,
23
- PACKAGE_MANAGER_TO_CDN
24
- } from './prepare.js'
25
-
26
- import { polyglotPlugin } from '@symbo.ls/polyglot'
27
- import { polyglotFunctions } from '@symbo.ls/polyglot/functions'
28
- import { helmetPlugin } from '@symbo.ls/helmet'
29
- import { fetchPlugin } from '@symbo.ls/fetch'
30
- import { capsizePlugin, capsizeHandler } from '@symbo.ls/capsize'
31
- import { shorthandPlugin } from '@symbo.ls/shorthand'
32
- import { analyzePlugin, createAnalyzeState } from '@symbo.ls/analyze'
33
- import { syncPlugin, notificationsPlugin } from '@symbo.ls/sync'
34
- import { inspectPlugin } from '@symbo.ls/inspect'
35
-
36
- // hydrate utilities available for future true-hydration opt-in
37
- // import { hydrate, assignBrKeysFromRegistry } from './hydrate.js'
38
-
39
- export const prepareContext = async (app, context = {}) => {
40
- // Identifier the runner uses to look up an app for teardown / instrumentation.
41
- // Prefer `{owner}--{key}` from symbols.json when both are present so two apps
42
- // with the same key but different owners stay distinguishable in shared realms.
43
- const cfg = context.symbolsConfig
44
- const symbolsKey = cfg?.owner && cfg?.key ? `${cfg.owner}--${cfg.key}` : cfg?.key
45
- const key = (context.key =
46
- context.key || symbolsKey || (isString(app) ? app : 'smblsapp'))
47
- context.define = context.define || defaultDefine
48
- context.cssPropsRegistry = CSS_PROPS_REGISTRY
49
- context.window = prepareWindow(context)
50
-
51
- if (context.sharedLibraries && context.sharedLibraries.length) {
52
- // Resolve string entries (e.g. 'system/default') by fetching from KV/API
53
- const hasStrings = context.sharedLibraries.some(lib => typeof lib === 'string')
54
- if (hasStrings) {
55
- const { resolveSharedLibraries } = await import('@symbo.ls/utils')
56
- context.sharedLibraries = await resolveSharedLibraries(context.sharedLibraries)
57
- }
58
- prepareSharedLibs(context)
59
- }
60
-
61
- const [scratcDesignSystem, registry] = prepareDesignSystem(
62
- key,
63
- context
64
- )
65
- context.designSystem = scratcDesignSystem
66
- context.registry = registry
67
-
68
- // Set up context.cases from context-level cases (defined in symbols/cases.js)
69
- if (!context.cases) context.cases = {}
70
-
71
- // Expand shorthand data early, before components/pages are merged with uikit
72
- if (context.shorthand) {
73
- shorthandPlugin.prepareContext(context)
74
- }
75
-
76
- const state = prepareState(app, context)
77
- context.state = state
78
- // Register the active root state in the framework registry so
79
- // `getRootState()` (called without `this`) can find it during early
80
- // render. Eliminates the requirement that projects pre-set
81
- // `window.smblsApp = { state }` in their `index.js` — the runner
82
- // bypasses project-side index.js entirely, and now no longer needs to.
83
- setActiveRootState(state)
84
- context.pages = preparePages(app, context)
85
- context.components = prepareComponents(context)
86
- context.utils = prepareUtils(context)
87
- if (PACKAGE_MANAGER_TO_CDN[context.packageManager]) {
88
- context.dependencies = await prepareDependencies(context)
89
- }
90
- context.methods = prepareMethods(context)
91
- context.routerOptions = initRouter(app, context)
92
- context.defaultExtends = [uikit.Box]
93
- context.snippets = context.snippets || {}
94
- context.functions = context.functions || {}
95
- context.plugins = context.plugins || []
96
-
97
- // Destringify globalScope: function strings → executable functions.
98
- // Functions are eval'd in a closure where all globalScope values are available,
99
- // so helpers can reference constants and other helpers naturally.
100
- if (context.globalScope && isObject(context.globalScope)) {
101
- context.globalScope = destringifyGlobalScope(context.globalScope)
102
- }
103
-
104
- // Rehydrate function-strings throughout the project tree. When frank
105
- // serializes a project for the platform it `.toString()`s every function
106
- // value (onClick, onRender, hide, transform, text-as-fn, etc.) into JSON.
107
- // Without this pass, the runtime would treat those strings as their
108
- // nominal type — invalid CSS for `transform`, dead listeners for
109
- // `onClick`, raw source code shown for `text`, etc. — which is the root
110
- // cause of every "works on dev / dead on remote" divergence we've ever
111
- // seen for v3.14 published projects. Walks the same buckets prepareContext
112
- // populated above, mutating each into a tree where every detectable
113
- // function-string has been `eval`'d back to a real function.
114
- // ESM-namespace-shaped buckets (`import * as functions from ...`) have
115
- // getter-only own properties — Object.assign throws on them. Some bundlers
116
- // (Parcel) emit such objects while keeping them extensible, so isExtensible
117
- // isn't reliable; use try/catch and reassign when mutation fails.
118
- const rehydrate = (target, key) => {
119
- const value = key ? target[key] : target
120
- if (!isObject(value)) return
121
- const destringified = deepDestringifyFunctions(value)
122
- try {
123
- Object.assign(value, destringified)
124
- } catch (e) {
125
- if (key) target[key] = destringified
126
- else throw e
127
- }
128
- }
129
- rehydrate(app)
130
- rehydrate(context, 'components')
131
- rehydrate(context, 'pages')
132
- rehydrate(context, 'functions')
133
- rehydrate(context, 'methods')
134
- rehydrate(context, 'snippets')
135
- rehydrate(context, 'app')
136
-
137
- // Clear adapter cache to ensure fresh resolution with current config
138
- if (context.fetch && context.fetch.__resolved) delete context.fetch.__resolved
139
- if (context.db && context.db.__resolved) delete context.db.__resolved
140
-
141
- // Auto-register plugins based on context config
142
- const hasPlugin = (name) => context.plugins.some(p => p.name === name)
143
-
144
- if (context.polyglot && !hasPlugin('polyglot')) {
145
- context.plugins.push(polyglotPlugin)
146
- for (const k in polyglotFunctions) {
147
- if (!(k in context.functions)) context.functions[k] = polyglotFunctions[k]
148
- }
149
- }
150
-
151
- if (!hasPlugin('helmet')) {
152
- context.plugins.push(helmetPlugin)
153
- }
154
-
155
- if (context.fetch && !hasPlugin('fetch')) {
156
- context.plugins.push(fetchPlugin)
157
- }
158
-
159
- if (context.designSystem?.typography?.useCapsize !== false && !hasPlugin('capsize')) {
160
- context.plugins.push(capsizePlugin)
161
- context.cssPropsRegistry.useCapsize = capsizeHandler
162
- }
163
-
164
- if (context.shorthand && !hasPlugin('shorthand')) {
165
- context.plugins.push(shorthandPlugin)
166
- }
167
-
168
- // Analyze plugin — runtime audit logger. Opt-in via `analyze: true` or
169
- // `analyze: { ... }`. Errors and warnings captured by default; everything
170
- // else off until explicitly enabled.
171
- if (context.analyze && !hasPlugin('analyze')) {
172
- const analyzeConfig = context.analyze === true ? {} : context.analyze
173
- context.analyze = createAnalyzeState(analyzeConfig)
174
- context.plugins.push(analyzePlugin)
175
- }
176
-
177
- // Sync plugin — HMR module for both transports (mermaid-served collab and
178
- // runner-served local). Plugged ON by default; users opt out by setting
179
- // `context.sync = false` (or `editor.liveSync = false`) or by removing
180
- // syncPlugin from `context.plugins` before calling `create()`. With
181
- // `context.sync = false` the plugin is never pushed, so SyncComponent
182
- // never reaches `app.extends` and no socket connection is attempted.
183
- if (context.sync !== false && !hasPlugin('sync')) {
184
- context.plugins.push(syncPlugin)
185
- }
186
-
187
- // Inspect plugin — element inspector overlay. Default OFF. Opt-in by
188
- // setting `context.inspect = true` (or a config object) — this auto-
189
- // registers the plugin which adds Alt+Shift highlight + click capture.
190
- // See `@symbo.ls/inspect` README for the shortcut + `editor.onInspect`
191
- // callback contract.
192
- if (context.inspect && !hasPlugin('inspect')) {
193
- context.plugins.push(inspectPlugin)
194
- }
195
-
196
- // Notifications plugin — toast overlay for sync connect/disconnect.
197
- // Default OFF. Opt-in via `context.notifications = true` (or the
198
- // legacy `editor.verbose = true` for backwards compat). Plugin's
199
- // beforeCreate filters again so flipping `context.notifications =
200
- // false` short-circuits even if the plugin is pushed manually.
201
- const notificationsOptIn = context.notifications === true ||
202
- (context.editor && context.editor.verbose === true)
203
- if (notificationsOptIn && context.notifications !== false && !hasPlugin('notifications')) {
204
- context.plugins.push(notificationsPlugin)
205
- }
206
-
207
- return context
208
- }
209
-
210
- export const createDomqlElement = async (app, ctx) => {
211
- if (!isObject(ctx)) ctx = {}
212
- if (isNode(app)) {
213
- app = {}
214
- ctx.parent = app
215
- } else if (isString(app)) {
216
- app = {}
217
- ctx.key = app
218
- } else if (!isObject(app)) {
219
- app = {}
220
- }
221
-
222
- // Detect brender BEFORE prepareContext so we can snapshot SSR styles.
223
- const win = ctx.window || (typeof window !== 'undefined' ? window : null)
224
- const isBrendered = win?.__BRENDER__
225
-
226
- // Snapshot SSR style tags BEFORE prepareContext creates CSS styles.
227
- // fallbackRender will only remove these — not the fresh CSS engine tag.
228
- let ssrStyles = null
229
- if (isBrendered) {
230
- const d = ctx.document || (typeof document !== 'undefined' ? document : null)
231
- if (d) ssrStyles = Array.from(d.head.querySelectorAll('style'))
232
- }
233
-
234
- await prepareContext(app, ctx)
235
-
236
- // Inject CSS reset after design system init
237
- if (ctx.useReset !== false) {
238
- const doc = ctx.document || (typeof document !== 'undefined' ? document : null)
239
- if (doc) {
240
- let style = doc.head.querySelector('style[data-smbls]')
241
- if (!style) {
242
- style = doc.createElement('style')
243
- style.setAttribute('data-smbls', '')
244
- doc.head.appendChild(style)
245
- }
246
- const s = style.sheet
247
- if (s) {
248
- try { s.insertRule('*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }', 0) } catch(e) {}
249
- try { s.insertRule('h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }', 1) } catch(e) {}
250
- }
251
- }
252
- }
253
-
254
- // Merge context.app (from app.js) onto root element definition
255
- if (ctx.app && isObject(ctx.app)) {
256
- for (const k in ctx.app) {
257
- if (app[k] === undefined) app[k] = ctx.app[k]
258
- }
259
- }
260
-
261
- app.extends = initializeExtend(app, ctx)
262
- if (ctx.router !== false) app.routes = ctx.pages
263
- app.state = ctx.state
264
- app.context = ctx
265
- app.data = app.data || {}
266
-
267
- if (!ctx.skipDesignSystemInit) {
268
- await prepareRequire(
269
- {
270
- functions: ctx.functions,
271
- utils: ctx.utils,
272
- snippets: ctx.snippets,
273
- ...ctx.files
274
- },
275
- ctx
276
- )
277
- }
278
-
279
- // Run plugin `beforeCreate` lifecycle. All sync/notifications/inspect
280
- // injection happens here — the framework knows nothing about which
281
- // plugins run. Remove the relevant plugin from `ctx.plugins` (or set
282
- // `context.sync = false` / `context.inspect = false` / etc) and no
283
- // attach happens.
284
- for (const plugin of ctx.plugins) {
285
- if (typeof plugin.beforeCreate === 'function') {
286
- try {
287
- plugin.beforeCreate(app, ctx)
288
- } catch (err) {
289
- console.error(`[smbls] plugin "${plugin.name || '?'}" beforeCreate error:`, err)
290
- }
291
- }
292
- }
293
-
294
- const doc = ctx.document
295
- if (!doc || !doc.createElement) return app
296
-
297
- const parentNode = ctx.parent || doc.body
298
-
299
- if (isBrendered) {
300
- return fallbackRender(createElement, app, parentNode, ctx, win, ssrStyles)
301
- }
302
-
303
- // v3.14: use @symbo.ls/element create directly
304
- const smblsApp = createElement(app, parentNode, ctx.key, {
305
- verbose: ctx.verbose,
306
- context: ctx,
307
- ...ctx.domqlOptions
308
- })
309
-
310
- // Keep activeDocument set to iframe doc so late-rendering elements
311
- // (lifecycle hooks, async children) inject CSS into the correct document.
312
- // The next create() call will set it to its own document.
313
-
314
- // Expose root element for debugging
315
- if (typeof window !== 'undefined' && !ctx.document) window.__smblsApp = smblsApp
316
-
317
- return smblsApp
318
- }
319
-
320
- /**
321
- * Legacy fallback: remove brender content and re-create DOMQL normally.
322
- * CSS stays in <style> tags so re-render is fast (no FOUC for styles).
323
- */
324
- const fallbackRender = async (createFn, app, parentNode, ctx, win, ssrStyles) => {
325
- const doc = parentNode.ownerDocument || document
326
-
327
- // Remove only the SSR style tags that existed before prepareContext.
328
- // This preserves the fresh <style> tag created by prepareDesignSystem.
329
- if (ssrStyles) ssrStyles.forEach(s => { if (s.parentNode) s.remove() })
330
-
331
- // Remove brender content but keep framework-injected elements:
332
- // <script>, <link>, <style> (page infrastructure)
333
- // <svg> with id (SVG/icon sprites injected by initDesignSystem)
334
- const toRemove = []
335
- for (const child of parentNode.childNodes) {
336
- if (child.nodeType === 1) {
337
- const tag = child.tagName.toLowerCase()
338
- if (tag === 'script' || tag === 'link' || tag === 'style') continue
339
- if (tag === 'svg' && child.id) continue // SVG sprite containers
340
- }
341
- toRemove.push(child)
342
- }
343
- toRemove.forEach(n => n.remove())
344
-
345
- // Also remove stale data-br attributes from any remaining elements
346
- doc.querySelectorAll('[data-br]').forEach(el => el.removeAttribute('data-br'))
347
-
348
- const smblsApp = createFn(app, parentNode, ctx.key, {
349
- verbose: ctx.verbose,
350
- context: ctx,
351
- ...ctx.domqlOptions
352
- })
353
-
354
- cleanup(win)
355
- return smblsApp
356
- }
357
-
358
- const cleanup = (win) => {
359
- if (!win) return
360
- delete win.__BRENDER__
361
- delete win.__BR_REGISTRY__
362
- }
package/src/define.js DELETED
@@ -1,64 +0,0 @@
1
- 'use strict'
2
-
3
- import { resolveMetadata, applyMetadata } from '@symbo.ls/helmet'
4
- import { executeFetch } from '@symbo.ls/fetch'
5
-
6
- const fetchHandler = (param, el, state, context) => {
7
- if (!param) return
8
- executeFetch(param, el, state, context)
9
- }
10
-
11
- const metadataHandler = (param, el, state) => {
12
- if (!param) return
13
- const doc = el.context?.document || (typeof document !== 'undefined' && document)
14
- if (!doc) return
15
- const resolved = resolveMetadata(param, el, state)
16
- applyMetadata(resolved, doc)
17
- }
18
-
19
- const routerHandler = async (param, el) => {
20
- if (!param) return
21
-
22
- const obj = { tag: 'fragment', ...param }
23
-
24
- const set = async () => {
25
- await el.set(obj, { preventDefineUpdate: '$router' })
26
- }
27
-
28
- if (el.lazyLoad) {
29
- window.requestAnimationFrame(set)
30
- } else await set()
31
-
32
- return obj
33
- }
34
-
35
- export const defaultDefine = {
36
- routes: param => param,
37
- metadata: metadataHandler,
38
- fetch: fetchHandler,
39
- $router: routerHandler
40
- }
41
-
42
- /**
43
- * Create a custom define object with optional features.
44
- *
45
- * @param {Object} opts
46
- * @param {boolean} [opts.fetch=true] - Include fetch handler
47
- * @param {boolean} [opts.metadata=true] - Include metadata/helmet handler
48
- * @param {boolean} [opts.router=true] - Include router handler
49
- * @returns {Object} define handlers
50
- *
51
- * @example
52
- * // Disable fetch:
53
- * context.define = createDefine({ fetch: false })
54
- *
55
- * // Only router:
56
- * context.define = createDefine({ fetch: false, metadata: false })
57
- */
58
- export const createDefine = (opts = {}) => {
59
- const define = { routes: param => param }
60
- if (opts.metadata !== false) define.metadata = metadataHandler
61
- if (opts.fetch !== false) define.fetch = fetchHandler
62
- if (opts.router !== false) define.$router = routerHandler
63
- return define
64
- }
package/src/destroy.js DELETED
@@ -1,66 +0,0 @@
1
- 'use strict'
2
-
3
- import { dispose } from '@symbo.ls/element'
4
-
5
- // destroy(app) — formal teardown for a smbls app instance. Mirrors create().
6
- //
7
- // Cleans up the side effects create()/createDomqlElement()/onpopstateRouter
8
- // register on the realm so a second app can mount cleanly, or so a long-lived
9
- // shell can swap apps without leaking listeners and stale memoized state.
10
- //
11
- // Order matters:
12
- // 1. Run app-level teardowns (popstate listener, custom hooks queued by
13
- // consumers on context.__teardowns) — these need to fire before the
14
- // element tree comes apart, since handlers may still read context.
15
- // 2. Walk the element tree via dispose() — fires `onBeforeRemove` /
16
- // `onRemove` hooks per element, disposes reactive effects + delegated
17
- // event listeners, removes DOM node, destroys owned state.
18
- // 3. Clear memoized adapters so a fresh re-create resolves fetch/db anew.
19
- //
20
- // What it does NOT do (deliberately):
21
- // - Strip rules from shared <style data-smbls> / <style data-smbls-scoped>
22
- // stylesheets. Those sheets are realm-wide by design (atomic CSS dedupe,
23
- // scoped-id rules). Orphan rules left behind are inert: their selectors
24
- // target content-hashed class names / unique scope IDs that no element in
25
- // the new app will ever have.
26
- //
27
- // Returns true if the app was torn down, false if it was already destroyed
28
- // (idempotent — safe to call twice).
29
- export const destroy = (app) => {
30
- if (!app || app.__destroyed) return false
31
- const ctx = app.context
32
- if (!ctx) {
33
- app.__destroyed = true
34
- return false
35
- }
36
-
37
- // 1. App-level teardowns (popstate listener etc.). Run before disposing
38
- // elements so cleanup callbacks can still read context state.
39
- if (Array.isArray(ctx.__teardowns)) {
40
- for (const fn of ctx.__teardowns) {
41
- try { fn() } catch (e) { console.error('[smbls] destroy teardown error:', e) }
42
- }
43
- ctx.__teardowns.length = 0
44
- }
45
-
46
- // 2. Recursive element disposal — fires onBeforeRemove / onRemove hooks,
47
- // cancels reactive effects, removes event listeners, detaches DOM, and
48
- // destroys state. Handles the entire subtree.
49
- try { dispose(app) } catch (e) { console.error('[smbls] dispose error:', e) }
50
-
51
- // 3. Clear memoized adapter caches so a re-create starts fresh.
52
- if (ctx.fetch && ctx.fetch.__resolved) delete ctx.fetch.__resolved
53
- if (ctx.fetch && ctx.fetch.__resolving) delete ctx.fetch.__resolving
54
- if (ctx.db && ctx.db.__resolved) delete ctx.db.__resolved
55
- if (ctx.db && ctx.db.__resolving) delete ctx.db.__resolving
56
-
57
- // 4. Tear down analyze listeners (browser, network, console proxy).
58
- if (ctx.analyze?.destroy) {
59
- try { ctx.analyze.destroy() } catch (e) { console.error('[analyze] destroy error:', e) }
60
- }
61
-
62
- app.__destroyed = true
63
- return true
64
- }
65
-
66
- export default destroy