smbls 3.2.3 → 3.2.7

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/prepare.js ADDED
@@ -0,0 +1,307 @@
1
+ 'use strict'
2
+
3
+ import {
4
+ isObject,
5
+ deepMerge,
6
+ deepClone,
7
+ merge,
8
+ isDevelopment,
9
+ matchesComponentNaming
10
+ } from '@domql/utils'
11
+ import { initEmotion } from '@symbo.ls/emotion'
12
+
13
+ import * as uikit from '@symbo.ls/uikit'
14
+ import * as utils from './utilImports.js'
15
+ import * as routerUtils from '@domql/router'
16
+
17
+ // @preserve-env
18
+
19
+ export const prepareWindow = (context) => {
20
+ if (typeof window === 'undefined') window = globalThis || {} // eslint-disable-line
21
+ if (typeof document === 'undefined') {
22
+ if (!window.document) window.document = globalThis.document || { body: {} }
23
+ document = window.document // eslint-disable-line
24
+ }
25
+ context.document = context.document || document
26
+ context.window = context.window || window
27
+ return context.window
28
+ }
29
+
30
+ function onlyDotsAndNumbers(str) {
31
+ return /^[0-9.]+$/.test(str) && str !== ''
32
+ }
33
+
34
+ const CDN_PROVIDERS = {
35
+ skypack: {
36
+ url: 'https://cdn.skypack.dev',
37
+ formatUrl: (pkg, version) =>
38
+ `${CDN_PROVIDERS.skypack.url}/${pkg}${version !== 'latest' ? `@${version}` : ''}`
39
+ },
40
+ esmsh: {
41
+ url: 'https://esm.sh',
42
+ formatUrl: (pkg, version) =>
43
+ `${CDN_PROVIDERS.esmsh.url}/${pkg}${version !== 'latest' ? `@${version}` : ''}`
44
+ },
45
+ unpkg: {
46
+ url: 'https://unpkg.com',
47
+ formatUrl: (pkg, version) =>
48
+ `${CDN_PROVIDERS.unpkg.url}/${pkg}${version !== 'latest' ? `@${version}` : ''}?module`
49
+ },
50
+ jsdelivr: {
51
+ url: 'https://cdn.jsdelivr.net/npm',
52
+ formatUrl: (pkg, version) =>
53
+ `${CDN_PROVIDERS.jsdelivr.url}/${pkg}${version !== 'latest' ? `@${version}` : ''}/+esm`
54
+ },
55
+ symbols: {
56
+ url: 'https://pkg.symbo.ls',
57
+ formatUrl: (pkg, version) => {
58
+ if (pkg.split('/').length > 2 || !onlyDotsAndNumbers(version)) {
59
+ return `${CDN_PROVIDERS.symbols.url}/${pkg}`
60
+ }
61
+ return `${CDN_PROVIDERS.symbols.url}/${pkg}/${version}.js`
62
+ }
63
+ }
64
+ }
65
+
66
+ // Maps symbols.json packageManager values to CDN_PROVIDERS keys
67
+ export const PACKAGE_MANAGER_TO_CDN = {
68
+ 'esm.sh': 'esmsh',
69
+ 'unpkg': 'unpkg',
70
+ 'skypack': 'skypack',
71
+ 'jsdelivr': 'jsdelivr',
72
+ 'pkg.symbo.ls': 'symbols'
73
+ }
74
+
75
+ /**
76
+ * Derive the CDN provider key from a symbols config object.
77
+ * Returns null when packageManager is a local tool (npm/yarn/pnpm/bun).
78
+ */
79
+ export const getCdnProviderFromConfig = (symbolsConfig = {}) => {
80
+ const { packageManager } = symbolsConfig
81
+ return PACKAGE_MANAGER_TO_CDN[packageManager] || null
82
+ }
83
+
84
+ export const getCDNUrl = (
85
+ packageName,
86
+ version = 'latest',
87
+ provider = 'esmsh'
88
+ ) => {
89
+ const cdnConfig = CDN_PROVIDERS[provider] || CDN_PROVIDERS.esmsh
90
+ return cdnConfig.formatUrl(packageName, version)
91
+ }
92
+
93
+ const UIkitWithPrefix = (prefix = 'smbls') => {
94
+ const newObj = {}
95
+ for (const key in uikit) {
96
+ if (Object.prototype.hasOwnProperty.call(uikit, key)) {
97
+ if (matchesComponentNaming(key)) {
98
+ newObj[`smbls.${key}`] = uikit[key]
99
+ } else {
100
+ newObj[key] = uikit[key]
101
+ }
102
+ }
103
+ }
104
+ return newObj
105
+ }
106
+
107
+ export const prepareComponents = (context) => {
108
+ return context.components
109
+ ? { ...UIkitWithPrefix(), ...context.components }
110
+ : UIkitWithPrefix()
111
+ }
112
+
113
+ export const prepareUtils = (context) => {
114
+ return {
115
+ ...utils,
116
+ ...routerUtils,
117
+ ...utils.scratchUtils,
118
+ ...context.utils,
119
+ ...context.snippets,
120
+ ...context.functions
121
+ }
122
+ }
123
+
124
+ export const prepareMethods = (context) => {
125
+ return {
126
+ ...(context.methods || {}),
127
+ require: context.utils.require,
128
+ requireOnDemand: context.utils.requireOnDemand,
129
+ router: context.utils.router
130
+ }
131
+ }
132
+
133
+ const cachedDeps = {}
134
+ export const prepareDependencies = async ({
135
+ dependencies,
136
+ dependenciesOnDemand,
137
+ document,
138
+ preventCaching = false,
139
+ cdnProvider,
140
+ packageManager,
141
+ symbolsConfig
142
+ }) => {
143
+ // Derive provider from packageManager or symbolsConfig when not explicitly passed
144
+ if (!cdnProvider) {
145
+ cdnProvider = PACKAGE_MANAGER_TO_CDN[packageManager] ||
146
+ getCdnProviderFromConfig(symbolsConfig) || 'esmsh'
147
+ }
148
+ if (!dependencies) return null
149
+ let hasAny = false
150
+ for (const _k in dependencies) { hasAny = true; break } // eslint-disable-line
151
+ if (!hasAny) return null
152
+
153
+ for (const dependency in dependencies) {
154
+ const version = dependencies[dependency]
155
+ if (dependenciesOnDemand && dependenciesOnDemand[dependency]) {
156
+ continue
157
+ }
158
+
159
+ const random = isDevelopment() && preventCaching ? `?${Math.random()}` : ''
160
+ const url = getCDNUrl(dependency, version, cdnProvider) + random
161
+
162
+ try {
163
+ if (cachedDeps[dependency]) return
164
+ cachedDeps[dependency] = true
165
+ await utils.loadRemoteScript(url, { document, type: 'module' })
166
+ } catch (e) {
167
+ console.error(`Failed to load ${dependency} from ${cdnProvider}:`, e)
168
+
169
+ if (cdnProvider !== 'symbols') {
170
+ try {
171
+ const fallbackUrl = getCDNUrl(dependency, version, 'symbols') + random
172
+ await utils.loadRemoteScript(fallbackUrl, { document })
173
+ console.log(
174
+ `Successfully loaded ${dependency} from fallback (symbols.ls)`
175
+ )
176
+ } catch (fallbackError) {
177
+ console.error(
178
+ `Failed to load ${dependency} from fallback:`,
179
+ fallbackError
180
+ )
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ return dependencies
187
+ }
188
+
189
+ export const prepareRequire = async (packages, ctx) => {
190
+ const windowOpts = ctx.window || window
191
+ const defaultProvider = ctx.cdnProvider ||
192
+ getCdnProviderFromConfig(ctx.symbolsConfig) || 'esmsh'
193
+
194
+ const initRequire = async (ctx) => async (key, provider) => {
195
+ const windowOpts = ctx.window || window
196
+ const pkg = windowOpts.packages[key]
197
+ if (typeof pkg === 'function') return pkg()
198
+ return pkg
199
+ }
200
+
201
+ const initRequireOnDemand =
202
+ async (ctx) =>
203
+ async (key, provider = defaultProvider) => {
204
+ const { dependenciesOnDemand } = ctx
205
+ const documentOpts = ctx.document || document
206
+ const windowOpts = ctx.window || window
207
+ if (!windowOpts.packages[key]) {
208
+ const random = isDevelopment() ? `?${Math.random()}` : ''
209
+ if (dependenciesOnDemand && dependenciesOnDemand[key]) {
210
+ const version = dependenciesOnDemand[key]
211
+ const url = getCDNUrl(key, version, provider) + random
212
+ try {
213
+ await ctx.utils.loadRemoteScript(url, {
214
+ window: windowOpts,
215
+ document: documentOpts
216
+ })
217
+ } catch (e) {
218
+ console.error(`Failed to load ${key} from ${provider}:`, e)
219
+ // Fallback to symbo if not already using it
220
+ if (provider !== 'symbols') {
221
+ const fallbackUrl = getCDNUrl(key, version, 'symbols') + random
222
+ await ctx.utils.loadRemoteScript(fallbackUrl, {
223
+ window: windowOpts,
224
+ document: documentOpts
225
+ })
226
+ }
227
+ }
228
+ } else {
229
+ const url = getCDNUrl(key, 'latest', provider) + random
230
+ try {
231
+ await ctx.utils.loadRemoteScript(url, {
232
+ window: windowOpts,
233
+ document: documentOpts
234
+ })
235
+ } catch (e) {
236
+ console.error(`Failed to load ${key} from ${provider}:`, e)
237
+ // Fallback to symbo if not already using it
238
+ if (provider !== 'symbols') {
239
+ const fallbackUrl = getCDNUrl(key, 'latest', 'symbols') + random
240
+ await ctx.utils.loadRemoteScript(fallbackUrl, {
241
+ window: windowOpts,
242
+ document: documentOpts
243
+ })
244
+ }
245
+ }
246
+ windowOpts.packages[key] = 'loadedOnDeman'
247
+ }
248
+ }
249
+ return await windowOpts.require(key, provider)
250
+ }
251
+
252
+ if (windowOpts.packages) {
253
+ windowOpts.packages = merge(windowOpts.packages, packages)
254
+ } else {
255
+ windowOpts.packages = packages
256
+ }
257
+
258
+ if (!windowOpts.require) {
259
+ ctx.utils.require = await initRequire(ctx)
260
+ windowOpts.require = ctx.utils.require
261
+ }
262
+
263
+ if (!windowOpts.requireOnDemand) {
264
+ ctx.utils.requireOnDemand = await initRequireOnDemand(ctx)
265
+ windowOpts.requireOnDemand = ctx.utils.requireOnDemand
266
+ }
267
+ }
268
+
269
+ export const prepareDesignSystem = (key, context) => {
270
+ const [scratcDesignhSystem, emotion, registry] = initEmotion(key, context)
271
+ return [scratcDesignhSystem, emotion, registry]
272
+ }
273
+
274
+ export const prepareState = (app, context) => {
275
+ const state = {}
276
+ if (context.state) utils.deepMerge(state, context.state)
277
+ if (app && app.state) deepMerge(state, app.state)
278
+ state.isRootState = true
279
+ return deepClone(state)
280
+ }
281
+
282
+ export const preparePages = (app, context) => {
283
+ if (isObject(app.routes) && isObject(context.pages)) {
284
+ merge(app.routes, context.pages)
285
+ }
286
+ const pages = app.routes || context.pages || {}
287
+ for (const v in pages) {
288
+ if (v.charCodeAt(0) === 47) continue // '/'
289
+ const index = v === 'index' ? '' : v
290
+ pages['/' + index] = pages[v]
291
+ delete pages[v]
292
+ }
293
+ return pages
294
+ }
295
+
296
+ export const prepareSharedLibs = (context) => {
297
+ const sharedLibraries = context.sharedLibraries
298
+ for (let i = 0; i < sharedLibraries.length; i++) {
299
+ const sharedLib = sharedLibraries[i]
300
+ if (context.type === 'template') {
301
+ overwriteShallow(context.designSystem, sharedLib.designSystem)
302
+ deepMerge(context, sharedLib, ['designSystem'], 1)
303
+ } else {
304
+ deepMerge(context, sharedLib, [], 1)
305
+ }
306
+ }
307
+ }
package/src/router.js ADDED
@@ -0,0 +1,73 @@
1
+ 'use strict'
2
+
3
+ import { window, deepMerge, merge, isUndefined } from '@domql/utils'
4
+ import { router as defaultRouter } from '@domql/router'
5
+ import { Link } from 'smbls'
6
+
7
+ const DEFAULT_ROUTING_OPTIONS = {
8
+ initRouter: true,
9
+ injectRouterInLinkComponent: true,
10
+ popState: true
11
+ }
12
+
13
+ export const initRouter = (element, context) => {
14
+ if (context.router === false) return
15
+ else if (context.router === true) context.router = DEFAULT_ROUTING_OPTIONS
16
+ else context.router = merge(context.router || {}, DEFAULT_ROUTING_OPTIONS)
17
+
18
+ const routerOptions = context.router
19
+
20
+ const onRouterRenderDefault = async (el, s) => {
21
+ const { pathname, search, hash } = window.location
22
+ const url = pathname + search + hash
23
+ if (el.routes) await defaultRouter(url, el, {}, { initialRender: true })
24
+ }
25
+
26
+ const hasRenderRouter =
27
+ (element.on && !isUndefined(element.on.renderRouter)) ||
28
+ !isUndefined(element.onRenderRouter) // || element.on.renderRouter
29
+ if (routerOptions && routerOptions.initRouter && !hasRenderRouter) {
30
+ if (element.on) {
31
+ element.on.renderRouter = onRouterRenderDefault
32
+ } else {
33
+ element.on = {
34
+ renderRouter: onRouterRenderDefault
35
+ }
36
+ }
37
+ }
38
+
39
+ injectRouterInLinkComponent(context, routerOptions)
40
+
41
+ return routerOptions
42
+ }
43
+
44
+ let popStateFired
45
+ export const onpopstateRouter = (element, context) => {
46
+ if (popStateFired) return
47
+ popStateFired = true
48
+ const routerOptions = context.router || DEFAULT_ROUTING_OPTIONS
49
+ if (!routerOptions.popState) return
50
+ const router =
51
+ context.utils && context.utils.router ? context.utils.router : defaultRouter
52
+ window.onpopstate = async e => {
53
+ const { pathname, search, hash } = window.location
54
+ const url = pathname + search + hash
55
+ await element.call(
56
+ 'router',
57
+ url,
58
+ element,
59
+ {},
60
+ { pushState: false, scrollToTop: false, level: 0, event: e }
61
+ )
62
+ }
63
+ }
64
+
65
+ export const injectRouterInLinkComponent = (context, routerOptions) => {
66
+ const { components } = context
67
+ if (routerOptions && routerOptions.injectRouterInLinkComponent) {
68
+ return deepMerge(
69
+ components['Link'] || components['smbls.Link'],
70
+ components['RouterLink'] || components['smbls.RouterLink']
71
+ )
72
+ }
73
+ }
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ import { isObjectLike, isUndefined, isDevelopment, isArray } from '@domql/utils'
4
+ import { SyncComponent, Inspect, Notifications } from '@symbo.ls/sync'
5
+
6
+ export const initializeExtend = (app, ctx) => {
7
+ return isObjectLike(app.extends) ? app.extends : []
8
+ }
9
+
10
+ export const initializeSync = (app, ctx) => {
11
+ const { editor } = ctx
12
+ if (!editor) return
13
+ const liveSync = isUndefined(editor.liveSync) ? isDevelopment() : editor.liveSync
14
+ if (liveSync) {
15
+ if (isArray(app.extends)) app.extends.push(SyncComponent)
16
+ else if (app.extends) {
17
+ app.extends = [app.extends, SyncComponent]
18
+ } else {
19
+ app.extends = [SyncComponent]
20
+ }
21
+ }
22
+ }
23
+
24
+ export const initializeInspect = (app, ctx) => {
25
+ const { editor } = ctx
26
+ if (!editor) return
27
+ const inspect = isUndefined(editor.inspect) ? isDevelopment() : editor.inspect
28
+ if (inspect) {
29
+ if (isArray(app.extends)) app.extends.push(Inspect)
30
+ else if (app.extends) {
31
+ app.extends = [app.extends, Inspect]
32
+ } else {
33
+ app.extends = [Inspect]
34
+ }
35
+ }
36
+ }
37
+
38
+ export const initializeNotifications = (app, ctx) => {
39
+ const { editor } = ctx
40
+ if (!editor) return
41
+ const verbose = isUndefined(editor.verbose) ? isDevelopment() || ctx.verbose : editor.verbose
42
+ if (verbose) {
43
+ if (isArray(app.extends)) app.extends.push(Notifications)
44
+ else if (app.extends) {
45
+ app.extends = [app.extends, Notifications]
46
+ } else {
47
+ app.extends = [Notifications]
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,10 @@
1
+ 'use strict'
2
+
3
+ import { scratchUtils, scratchSystem, set } from '@symbo.ls/scratch'
4
+
5
+ export { scratchUtils, scratchSystem, set }
6
+ export * from '@domql/utils'
7
+ export * from '@symbo.ls/smbls-utils'
8
+ export { init, reinit, applyCSS } from './init.js'
9
+ export * from '@domql/report'
10
+ export * from '@domql/router'
@@ -1,4 +0,0 @@
1
- {
2
- "type": "commonjs",
3
- "main": "index.js"
4
- }