@muze-labs/simplyflow 0.9.0 → 0.10.2
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/README.md +72 -16
- package/dist/simply.flow.js +458 -298
- package/dist/simply.flow.min.js +1 -1
- package/dist/simply.flow.min.js.map +4 -4
- package/package.json +29 -42
- package/src/action.mjs +1 -64
- package/src/app.mjs +1 -282
- package/src/behavior.mjs +1 -121
- package/src/bind-render.mjs +1 -0
- package/src/bind-transformers.mjs +1 -0
- package/src/bind.mjs +1 -522
- package/src/command.mjs +1 -225
- package/src/dom.mjs +1 -274
- package/src/highlight.mjs +1 -11
- package/src/include.mjs +1 -239
- package/src/{flow.mjs → index.mjs} +13 -13
- package/src/model.mjs +1 -290
- package/src/path.mjs +1 -47
- package/src/route.mjs +1 -418
- package/src/shortcut.mjs +1 -146
- package/src/state.mjs +1 -1347
- package/src/suggest.mjs +1 -68
- package/src/symbols.mjs +1 -9
- package/MUZE_ALIGNMENT.md +0 -118
- package/src/bind.render.mjs +0 -694
- package/src/bind.transformers.mjs +0 -25
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muze-labs/simplyflow",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Reactive browser applications with signals, effects, data binding and an app layer",
|
|
3
|
+
"version": "0.10.2",
|
|
4
|
+
"description": "Reactive browser applications with signals, effects, data binding and an app layer.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./src/
|
|
6
|
+
"main": "./src/index.mjs",
|
|
7
7
|
"exports": {
|
|
8
|
-
".": "./src/
|
|
8
|
+
".": "./src/index.mjs",
|
|
9
9
|
"./app": "./src/app.mjs",
|
|
10
10
|
"./state": "./src/state.mjs",
|
|
11
11
|
"./bind": "./src/bind.mjs",
|
|
12
|
+
"./bind/render": "./src/bind-render.mjs",
|
|
13
|
+
"./bind/transformers": "./src/bind-transformers.mjs",
|
|
12
14
|
"./model": "./src/model.mjs",
|
|
13
15
|
"./dom": "./src/dom.mjs",
|
|
14
16
|
"./path": "./src/path.mjs",
|
|
@@ -19,54 +21,39 @@
|
|
|
19
21
|
"./includes": "./src/include.mjs",
|
|
20
22
|
"./shortcuts": "./src/shortcut.mjs",
|
|
21
23
|
"./highlight": "./src/highlight.mjs",
|
|
24
|
+
"./render": "./src/render.mjs",
|
|
25
|
+
"./suggest": "./src/suggest.mjs",
|
|
26
|
+
"./symbols": "./src/symbols.mjs",
|
|
22
27
|
"./dist/simply.flow.js": "./dist/simply.flow.js",
|
|
23
28
|
"./dist/simply.flow.min.js": "./dist/simply.flow.min.js",
|
|
24
29
|
"./package.json": "./package.json"
|
|
25
30
|
},
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
31
|
+
"sideEffects": [
|
|
32
|
+
"./src/index.mjs",
|
|
33
|
+
"./src/render.mjs"
|
|
34
|
+
],
|
|
35
|
+
"files": [
|
|
36
|
+
"src/",
|
|
37
|
+
"dist/"
|
|
38
|
+
],
|
|
29
39
|
"scripts": {
|
|
30
|
-
"build": "esbuild src/
|
|
31
|
-
"build-dev": "esbuild src/
|
|
32
|
-
"
|
|
33
|
-
|
|
40
|
+
"build": "esbuild src/index.mjs --bundle --outfile=dist/simply.flow.min.js --minify --sourcemap",
|
|
41
|
+
"build-dev": "esbuild src/index.mjs --bundle --outfile=dist/simply.flow.js",
|
|
42
|
+
"dev": "watch 'npm run build-dev' ./src ../state/src ../bind/src ../model/src ../app/src & npx http-server ../.."
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@muze-labs/simplyflow-state": "0.10.1",
|
|
46
|
+
"@muze-labs/simplyflow-bind": "0.10.1",
|
|
47
|
+
"@muze-labs/simplyflow-model": "0.10.1",
|
|
48
|
+
"@muze-labs/simplyflow-app": "0.10.1"
|
|
34
49
|
},
|
|
50
|
+
"license": "MIT",
|
|
35
51
|
"repository": {
|
|
36
52
|
"type": "git",
|
|
37
53
|
"url": "git+https://github.com/muze-labs/simplyflow.git"
|
|
38
54
|
},
|
|
39
|
-
"keywords": [
|
|
40
|
-
"UI",
|
|
41
|
-
"components",
|
|
42
|
-
"declarative",
|
|
43
|
-
"reactive"
|
|
44
|
-
],
|
|
45
|
-
"author": "auke@muze.nl",
|
|
46
|
-
"license": "MIT",
|
|
47
55
|
"bugs": {
|
|
48
56
|
"url": "https://github.com/muze-labs/simplyflow/issues"
|
|
49
57
|
},
|
|
50
|
-
"homepage": "https://github.com/muze-labs/simplyflow#readme"
|
|
51
|
-
|
|
52
|
-
"node": ">=20.0.0"
|
|
53
|
-
},
|
|
54
|
-
"devDependencies": {
|
|
55
|
-
"@eslint/js": "^9.17.0",
|
|
56
|
-
"esbuild": "^0.24.2",
|
|
57
|
-
"globals": "^15.13.0",
|
|
58
|
-
"jest": "^29.7.0",
|
|
59
|
-
"jest-environment-jsdom": "^29.7.0",
|
|
60
|
-
"watch": "^1.0.2"
|
|
61
|
-
},
|
|
62
|
-
"files": [
|
|
63
|
-
"README.md",
|
|
64
|
-
"MUZE_ALIGNMENT.md",
|
|
65
|
-
"dist/",
|
|
66
|
-
"src/"
|
|
67
|
-
],
|
|
68
|
-
"jest": {
|
|
69
|
-
"transform": {},
|
|
70
|
-
"testEnvironment": "jsdom"
|
|
71
|
-
}
|
|
72
|
-
}
|
|
58
|
+
"homepage": "https://github.com/muze-labs/simplyflow#readme"
|
|
59
|
+
}
|
package/src/action.mjs
CHANGED
|
@@ -1,64 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const warnedUnknownActions = new WeakMap()
|
|
4
|
-
|
|
5
|
-
export function actions(options)
|
|
6
|
-
{
|
|
7
|
-
if (options.app) {
|
|
8
|
-
const functionHandler = {
|
|
9
|
-
apply(target, thisArg, argumentsList)
|
|
10
|
-
{
|
|
11
|
-
try {
|
|
12
|
-
const result = target(...argumentsList)
|
|
13
|
-
if (result instanceof Promise) {
|
|
14
|
-
return result.catch(err => {
|
|
15
|
-
return options.app.onError.call(this, err, target)
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
return result
|
|
19
|
-
} catch(err) {
|
|
20
|
-
return options.app.onError.call(this, err, target)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const actionHandler = {
|
|
26
|
-
get(target, property)
|
|
27
|
-
{
|
|
28
|
-
if (!Object.hasOwn(target, property)) {
|
|
29
|
-
warnUnknownAction(target, property)
|
|
30
|
-
return undefined
|
|
31
|
-
}
|
|
32
|
-
if (options.app.onError) {
|
|
33
|
-
return new Proxy(target[property].bind(options.app), functionHandler)
|
|
34
|
-
} else {
|
|
35
|
-
return target[property].bind(options.app)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return new Proxy(options.actions, actionHandler)
|
|
40
|
-
} else {
|
|
41
|
-
return options
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function warnUnknownAction(actions, property)
|
|
46
|
-
{
|
|
47
|
-
if (typeof property !== 'string') {
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
let warned = warnedUnknownActions.get(actions)
|
|
52
|
-
if (!warned) {
|
|
53
|
-
warned = new Set()
|
|
54
|
-
warnedUnknownActions.set(actions, warned)
|
|
55
|
-
}
|
|
56
|
-
if (warned.has(property)) {
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
warned.add(property)
|
|
60
|
-
|
|
61
|
-
const suggestion = closest(property, Object.keys(actions))
|
|
62
|
-
const suffix = suggestion ? `. Did you mean "${suggestion}"?` : ''
|
|
63
|
-
console.warn(`simplyflow/action: unknown action "${property}"${suffix}`)
|
|
64
|
-
}
|
|
1
|
+
export * from '@muze-labs/simplyflow-app/action'
|
package/src/app.mjs
CHANGED
|
@@ -1,282 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { signal } from './state.mjs'
|
|
3
|
-
import { routes } from './route.mjs'
|
|
4
|
-
import { commands, destroyCommands } from './command.mjs'
|
|
5
|
-
import { actions } from './action.mjs'
|
|
6
|
-
import { shortcuts, destroyShortcuts, accesskeys, destroyAccesskeys } from './shortcut.mjs'
|
|
7
|
-
import { behaviors } from './behavior.mjs'
|
|
8
|
-
import { includes } from './include.mjs'
|
|
9
|
-
import { closest } from './suggest.mjs'
|
|
10
|
-
|
|
11
|
-
const APP_OPTIONS = [
|
|
12
|
-
'container',
|
|
13
|
-
'data',
|
|
14
|
-
'templates',
|
|
15
|
-
'styles',
|
|
16
|
-
'start',
|
|
17
|
-
'onError',
|
|
18
|
-
'components',
|
|
19
|
-
'behaviors',
|
|
20
|
-
'baseURL',
|
|
21
|
-
'commands',
|
|
22
|
-
'shortcuts',
|
|
23
|
-
'routes',
|
|
24
|
-
'actions'
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
class SimplyApp
|
|
28
|
-
{
|
|
29
|
-
constructor(options={})
|
|
30
|
-
{
|
|
31
|
-
if (options.components) {
|
|
32
|
-
const mergedOptions = {}
|
|
33
|
-
mergeComponents(mergedOptions, options.components)
|
|
34
|
-
mergeOptions(mergedOptions, options) // app options override component options
|
|
35
|
-
options = mergedOptions
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.container = options.container || document.body
|
|
40
|
-
this.destroyed = false
|
|
41
|
-
this.data = signal(options.data || {})
|
|
42
|
-
this.start = options.start
|
|
43
|
-
this.onError = options.onError
|
|
44
|
-
this.components = options.components
|
|
45
|
-
this.baseURL = options.baseURL
|
|
46
|
-
|
|
47
|
-
installTemplates(this.container, options.templates)
|
|
48
|
-
installStyles(this.container, options.styles)
|
|
49
|
-
|
|
50
|
-
for (const key of Object.keys(options)) {
|
|
51
|
-
switch(key) {
|
|
52
|
-
case 'container':
|
|
53
|
-
case 'data':
|
|
54
|
-
case 'templates':
|
|
55
|
-
case 'styles':
|
|
56
|
-
case 'start':
|
|
57
|
-
case 'onError':
|
|
58
|
-
case 'components':
|
|
59
|
-
case 'baseURL':
|
|
60
|
-
break
|
|
61
|
-
case 'commands':
|
|
62
|
-
this.commands = commands({ app: this, container: this.container, commands: options.commands})
|
|
63
|
-
break
|
|
64
|
-
case 'shortcuts':
|
|
65
|
-
this.shortcuts = shortcuts({ app: this, shortcuts: options.shortcuts })
|
|
66
|
-
break
|
|
67
|
-
case 'behaviors':
|
|
68
|
-
this.behaviors = behaviors({ app: this, container: this.container, behaviors: options.behaviors })
|
|
69
|
-
break
|
|
70
|
-
case 'routes':
|
|
71
|
-
this.routes = routes({ app: this, routes: options.routes})
|
|
72
|
-
break
|
|
73
|
-
case 'actions':
|
|
74
|
-
this.actions = actions({app: this, actions: options.actions})
|
|
75
|
-
break
|
|
76
|
-
case 'prototype':
|
|
77
|
-
case '__proto__':
|
|
78
|
-
// ignore this to avoid prototype pollution
|
|
79
|
-
break
|
|
80
|
-
default:
|
|
81
|
-
// Unknown options become app properties. Warn only when the
|
|
82
|
-
// name is close to a built-in option, which usually means a typo.
|
|
83
|
-
warnLikelyOptionTypo(key)
|
|
84
|
-
this[key] = options[key]
|
|
85
|
-
break
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this.binding = bind({
|
|
90
|
-
root: this.data,
|
|
91
|
-
container: this.container,
|
|
92
|
-
attribute: 'data-simply'
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
this.includes = includes({ container: this.container })
|
|
96
|
-
|
|
97
|
-
this.accesskeys = accesskeys({ app: this, container: this.container })
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
get app()
|
|
101
|
-
{
|
|
102
|
-
return this
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
destroy()
|
|
106
|
-
{
|
|
107
|
-
this.destroyed = true
|
|
108
|
-
if (this.binding) {
|
|
109
|
-
this.binding.destroy()
|
|
110
|
-
this.binding = undefined
|
|
111
|
-
}
|
|
112
|
-
if (this.commands) {
|
|
113
|
-
destroyCommands(this.commands)
|
|
114
|
-
}
|
|
115
|
-
if (this.shortcuts) {
|
|
116
|
-
destroyShortcuts(this.shortcuts)
|
|
117
|
-
}
|
|
118
|
-
if (this.accesskeys) {
|
|
119
|
-
destroyAccesskeys(this.accesskeys)
|
|
120
|
-
this.accesskeys = undefined
|
|
121
|
-
}
|
|
122
|
-
if (this.routes) {
|
|
123
|
-
this.routes.destroy()
|
|
124
|
-
this.routes = undefined
|
|
125
|
-
}
|
|
126
|
-
if (this.behaviors) {
|
|
127
|
-
this.behaviors.destroy()
|
|
128
|
-
this.behaviors = undefined
|
|
129
|
-
}
|
|
130
|
-
if (this.includes) {
|
|
131
|
-
this.includes.destroy()
|
|
132
|
-
this.includes = undefined
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function installTemplates(container, templates)
|
|
138
|
-
{
|
|
139
|
-
if (!templates) {
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
for (const name of Object.keys(templates)) {
|
|
143
|
-
const element = document.createElement('div')
|
|
144
|
-
element.innerHTML = templates[name]
|
|
145
|
-
let template = container.querySelector('template#'+name)
|
|
146
|
-
if (!template) {
|
|
147
|
-
template = document.createElement('template')
|
|
148
|
-
template.id = name
|
|
149
|
-
template.content.append(...element.children)
|
|
150
|
-
container.appendChild(template)
|
|
151
|
-
} else {
|
|
152
|
-
template.content.replaceChildren(...element.children)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function installStyles(container, styles)
|
|
158
|
-
{
|
|
159
|
-
if (!styles) {
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
|
-
for (const name of Object.keys(styles)) {
|
|
163
|
-
let style = container.querySelector('style#'+name+'.css')
|
|
164
|
-
if (!style) {
|
|
165
|
-
style = document.createElement('style')
|
|
166
|
-
style.id = name+'.css'
|
|
167
|
-
container.appendChild(style)
|
|
168
|
-
}
|
|
169
|
-
style.innerHTML = styles[name]
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
function warnLikelyOptionTypo(key)
|
|
175
|
-
{
|
|
176
|
-
const suggestion = closest(key, APP_OPTIONS)
|
|
177
|
-
if (suggestion) {
|
|
178
|
-
console.warn(`simplyflow/app: unknown option "${key}". Did you mean "${suggestion}"? The option was still added to the app as "app.${key}".`)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function initRoutes(app) {
|
|
183
|
-
if (app.destroyed) {
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
if (app.routes) {
|
|
187
|
-
if (app.baseURL) {
|
|
188
|
-
app.routes.init({ baseURL: app.baseURL })
|
|
189
|
-
}
|
|
190
|
-
app.routes.handleEvents()
|
|
191
|
-
globalThis.setTimeout(() => {
|
|
192
|
-
if (app.destroyed || !app.routes) {
|
|
193
|
-
return
|
|
194
|
-
}
|
|
195
|
-
if (app.routes.has(globalThis.location?.hash)) {
|
|
196
|
-
app.routes.match(globalThis.location.hash)
|
|
197
|
-
} else {
|
|
198
|
-
app.routes.match(globalThis.location?.pathname+globalThis.location?.hash)
|
|
199
|
-
}
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
function handleAppError(app, error, context)
|
|
206
|
-
{
|
|
207
|
-
if (app.onError) {
|
|
208
|
-
return app.onError.call(app, error, context)
|
|
209
|
-
}
|
|
210
|
-
throw error
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function app(options={})
|
|
214
|
-
{
|
|
215
|
-
const app = new SimplyApp(options)
|
|
216
|
-
if (!app.start) {
|
|
217
|
-
initRoutes(app)
|
|
218
|
-
return app
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
const result = app.start.call(app)
|
|
223
|
-
if (result instanceof Promise) {
|
|
224
|
-
result.then(() => initRoutes(app)).catch(error => handleAppError(app, error, app.start))
|
|
225
|
-
} else {
|
|
226
|
-
initRoutes(app)
|
|
227
|
-
}
|
|
228
|
-
} catch (error) {
|
|
229
|
-
handleAppError(app, error, app.start)
|
|
230
|
-
}
|
|
231
|
-
return app
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
function mergeOptions(options, otherOptions)
|
|
236
|
-
{
|
|
237
|
-
for (const key of Object.keys(otherOptions)) {
|
|
238
|
-
switch(typeof otherOptions[key]) {
|
|
239
|
-
case 'object':
|
|
240
|
-
if (!otherOptions[key]) {
|
|
241
|
-
continue // null
|
|
242
|
-
}
|
|
243
|
-
if (!options[key]) {
|
|
244
|
-
options[key] = otherOptions[key]
|
|
245
|
-
} else {
|
|
246
|
-
mergeOptions(options[key], otherOptions[key])
|
|
247
|
-
}
|
|
248
|
-
break
|
|
249
|
-
default:
|
|
250
|
-
options[key] = otherOptions[key]
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function mergeComponents(options, components) {
|
|
256
|
-
for (const name of Object.keys(components)) {
|
|
257
|
-
const component = components[name]
|
|
258
|
-
if (component.components) {
|
|
259
|
-
mergeComponents(options, component.components)
|
|
260
|
-
}
|
|
261
|
-
if (!options.components) {
|
|
262
|
-
options.components = {}
|
|
263
|
-
}
|
|
264
|
-
options.components[name] = component
|
|
265
|
-
for (const key of Object.keys(component)) {
|
|
266
|
-
switch(key) {
|
|
267
|
-
case 'start':
|
|
268
|
-
case 'onError':
|
|
269
|
-
// App lifecycle functions are app-level behavior, not merged component state.
|
|
270
|
-
case 'components':
|
|
271
|
-
// already handled
|
|
272
|
-
break
|
|
273
|
-
default:
|
|
274
|
-
if (!options[key]) {
|
|
275
|
-
options[key] = Object.create(null)
|
|
276
|
-
}
|
|
277
|
-
mergeOptions(options[key], component[key])
|
|
278
|
-
break
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
1
|
+
export * from '@muze-labs/simplyflow-app'
|
package/src/behavior.mjs
CHANGED
|
@@ -1,121 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const BEHAVIOR_SELECTOR = '[data-simply-behavior]'
|
|
4
|
-
|
|
5
|
-
class SimplyBehaviors
|
|
6
|
-
{
|
|
7
|
-
constructor(options = {})
|
|
8
|
-
{
|
|
9
|
-
this.app = options.app
|
|
10
|
-
this.container = options.container || document.body
|
|
11
|
-
this.behaviors = options.behaviors || {}
|
|
12
|
-
this.active = new Set()
|
|
13
|
-
this.cleanups = new WeakMap()
|
|
14
|
-
this.unknown = new Set()
|
|
15
|
-
|
|
16
|
-
this.observer = new MutationObserver((changes) => this.handleChanges(changes))
|
|
17
|
-
this.observer.observe(this.container, {
|
|
18
|
-
subtree: true,
|
|
19
|
-
childList: true
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
for (const node of behaviorNodes(this.container)) {
|
|
23
|
-
this.start(node)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
start(node)
|
|
28
|
-
{
|
|
29
|
-
if (this.active.has(node)) {
|
|
30
|
-
return
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const name = node?.dataset?.simplyBehavior
|
|
34
|
-
const behavior = this.behaviors[name]
|
|
35
|
-
if (!name || typeof behavior !== 'function') {
|
|
36
|
-
this.warnUnknown(name, node)
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.active.add(node)
|
|
41
|
-
const cleanup = behavior.call(this.app || node, node)
|
|
42
|
-
if (typeof cleanup === 'function') {
|
|
43
|
-
this.cleanups.set(node, cleanup)
|
|
44
|
-
} else if (typeof cleanup !== 'undefined') {
|
|
45
|
-
console.warn('simplyflow/behavior: behavior may only return a cleanup function', { cause: cleanup })
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
stop(node)
|
|
50
|
-
{
|
|
51
|
-
if (!this.active.has(node)) {
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
this.active.delete(node)
|
|
55
|
-
|
|
56
|
-
const cleanup = this.cleanups.get(node)
|
|
57
|
-
this.cleanups.delete(node)
|
|
58
|
-
if (cleanup) {
|
|
59
|
-
cleanup.call(this.app || node, node)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
handleChanges(changes)
|
|
64
|
-
{
|
|
65
|
-
const added = []
|
|
66
|
-
for (const change of changes) {
|
|
67
|
-
if (change.type !== 'childList') {
|
|
68
|
-
continue
|
|
69
|
-
}
|
|
70
|
-
for (const node of change.removedNodes) {
|
|
71
|
-
for (const behaviorNode of behaviorNodes(node)) {
|
|
72
|
-
this.stop(behaviorNode)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
for (const node of change.addedNodes) {
|
|
76
|
-
added.push(...behaviorNodes(node))
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
for (const node of added) {
|
|
80
|
-
this.start(node)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
warnUnknown(name, node)
|
|
85
|
-
{
|
|
86
|
-
if (!name || this.unknown.has(name)) {
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
this.unknown.add(name)
|
|
90
|
-
|
|
91
|
-
const suggestion = closest(name, Object.keys(this.behaviors))
|
|
92
|
-
const suffix = suggestion ? `. Did you mean "${suggestion}"?` : ''
|
|
93
|
-
console.warn(`simplyflow/behavior: unknown behavior "${name}"${suffix}`, { cause: node })
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
destroy()
|
|
97
|
-
{
|
|
98
|
-
this.observer.disconnect()
|
|
99
|
-
for (const node of Array.from(this.active)) {
|
|
100
|
-
this.stop(node)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function behaviors(options = {})
|
|
106
|
-
{
|
|
107
|
-
return new SimplyBehaviors(options)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function behaviorNodes(root)
|
|
111
|
-
{
|
|
112
|
-
if (!root?.querySelectorAll) {
|
|
113
|
-
return []
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const nodes = Array.from(root.querySelectorAll(BEHAVIOR_SELECTOR))
|
|
117
|
-
if (root.matches?.(BEHAVIOR_SELECTOR)) {
|
|
118
|
-
nodes.unshift(root)
|
|
119
|
-
}
|
|
120
|
-
return nodes
|
|
121
|
-
}
|
|
1
|
+
export * from '@muze-labs/simplyflow-app/behavior'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@muze-labs/simplyflow-bind/render'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@muze-labs/simplyflow-bind/transformers'
|