simplyflow 0.8.2 → 0.9.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/dist/simply.flow.js +207 -100
- package/dist/simply.flow.min.js +1 -1
- package/dist/simply.flow.min.js.map +4 -4
- package/package.json +1 -1
- package/src/bind.mjs +3 -5
- package/src/bind.render.mjs +18 -10
- package/src/dom.mjs +39 -5
- package/src/edit/anchor.mjs +130 -0
- package/src/edit/toolbars.mjs +315 -0
- package/src/edit.mjs +168 -83
- package/src/model.mjs +2 -1
- package/src/state.mjs +205 -95
- package/src/symbols.mjs +8 -0
package/src/state.mjs
CHANGED
|
@@ -1,55 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { DEP } from './symbols.mjs'
|
|
2
|
+
|
|
3
|
+
function wrapMapMethod(target, property, receiver, value) {
|
|
4
|
+
return (...args) => {
|
|
5
|
+
if (property === 'get' || property === 'has') {
|
|
6
|
+
notifyGet(receiver, args[0])
|
|
7
|
+
}
|
|
8
|
+
if (['keys', 'values', 'entries', 'forEach', Symbol.iterator].includes(property)) {
|
|
9
|
+
notifyGet(receiver, DEP.ITERATE)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const oldSize = target.size
|
|
13
|
+
const result = value.apply(target, args)
|
|
14
|
+
|
|
15
|
+
if (property === 'set') {
|
|
16
|
+
notifySet(receiver, makeContext(args[0], { now: args[1] }))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (property === 'delete') {
|
|
20
|
+
notifySet(receiver, makeContext(args[0], { delete: true}))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (oldSize !== target.size) {
|
|
24
|
+
notifySet(receiver, makeContext(DEP.SIZE, {}))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (['set','delete','clear'].includes(property) || oldSize!==target.size) {
|
|
28
|
+
notifySet(receiver, makeContext(DEP.ITERATE, {}))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return result
|
|
32
|
+
}
|
|
33
|
+
|
|
3
34
|
}
|
|
4
|
-
|
|
5
|
-
|
|
35
|
+
|
|
36
|
+
function wrapArrayMethod(target, property, receiver, value) {
|
|
37
|
+
return (...args) => {
|
|
38
|
+
let l = target.length
|
|
39
|
+
// by binding the function to the receiver
|
|
40
|
+
// all accesses in the function will be trapped
|
|
41
|
+
// by the Proxy, so get/set/delete is all handled
|
|
42
|
+
let result = value.apply(receiver, args)
|
|
43
|
+
if (l != target.length) {
|
|
44
|
+
notifySet(receiver, makeContext(DEP.LENGTH, { was: l, now: target.length }) )
|
|
45
|
+
}
|
|
46
|
+
return result
|
|
47
|
+
}
|
|
6
48
|
}
|
|
7
|
-
|
|
8
|
-
|
|
49
|
+
|
|
50
|
+
function wrapSetMethod(target, property, receiver, value) {
|
|
51
|
+
return (...args) => {
|
|
52
|
+
// node doesn't allow you to call set/map functions
|
|
53
|
+
// bound to the receiver.. so using target instead
|
|
54
|
+
// there are no properties to update anyway, except for size
|
|
55
|
+
let s = target.size
|
|
56
|
+
let result = value.apply(target, args)
|
|
57
|
+
if (s != target.size) {
|
|
58
|
+
notifySet(receiver, makeContext( DEP.SIZE, { was: s, now: target.size }) )
|
|
59
|
+
}
|
|
60
|
+
// there is no efficient way to see if the function called
|
|
61
|
+
// has actually changed the Set/Map, but by assuming the
|
|
62
|
+
// 'setter' functions will change the results of the
|
|
63
|
+
// 'getter' functions, effects should update correctly
|
|
64
|
+
if (['set','add','clear','delete'].includes(property)) {
|
|
65
|
+
notifySet(receiver, makeContext( { entries: {}, forEach: {}, has: {}, keys: {}, values: {}, [Symbol.iterator]: {} } ) )
|
|
66
|
+
}
|
|
67
|
+
return result
|
|
68
|
+
}
|
|
9
69
|
}
|
|
10
70
|
|
|
11
71
|
const signalHandler = {
|
|
12
72
|
get: (target, property, receiver) => {
|
|
13
|
-
if (property===
|
|
73
|
+
if (property===DEP.XRAY) {
|
|
14
74
|
return target // don't notifyGet here, this is only called by set
|
|
15
75
|
}
|
|
16
|
-
if (property===
|
|
76
|
+
if (property===DEP.SIGNAL) {
|
|
17
77
|
return true
|
|
18
78
|
}
|
|
19
79
|
const value = target?.[property] // Reflect.get fails on a Set.
|
|
20
80
|
notifyGet(receiver, property)
|
|
21
81
|
if (typeof value === 'function') {
|
|
22
82
|
if (Array.isArray(target)) {
|
|
23
|
-
return (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let result = value.apply(receiver, args)
|
|
29
|
-
if (l != target.length) {
|
|
30
|
-
notifySet(receiver, makeContext('length', { was: l, now: target.length }) )
|
|
31
|
-
}
|
|
32
|
-
return result
|
|
33
|
-
}
|
|
34
|
-
} else if (target instanceof Set || target instanceof Map) {
|
|
35
|
-
return (...args) => {
|
|
36
|
-
// node doesn't allow you to call set/map functions
|
|
37
|
-
// bound to the receiver.. so using target instead
|
|
38
|
-
// there are no properties to update anyway, except for size
|
|
39
|
-
let s = target.size
|
|
40
|
-
let result = value.apply(target, args)
|
|
41
|
-
if (s != target.size) {
|
|
42
|
-
notifySet(receiver, makeContext( 'size', { was: s, now: target.size }) )
|
|
43
|
-
}
|
|
44
|
-
// there is no efficient way to see if the function called
|
|
45
|
-
// has actually changed the Set/Map, but by assuming the
|
|
46
|
-
// 'setter' functions will change the results of the
|
|
47
|
-
// 'getter' functions, effects should update correctly
|
|
48
|
-
if (['set','add','clear','delete'].includes(property)) {
|
|
49
|
-
notifySet(receiver, makeContext( { entries: {}, forEach: {}, has: {}, keys: {}, values: {}, [Symbol.iterator]: {} } ) )
|
|
50
|
-
}
|
|
51
|
-
return result
|
|
52
|
-
}
|
|
83
|
+
return wrapArrayMethod(target, property, receiver, value)
|
|
84
|
+
} else if (target instanceof Map) {
|
|
85
|
+
return wrapMapMethod(target, property, receiver, value)
|
|
86
|
+
} else if (target instanceof Set) {
|
|
87
|
+
return wrapSetMethod(target, property, receiver, value)
|
|
53
88
|
} else if (
|
|
54
89
|
target instanceof HTMLElement
|
|
55
90
|
|| target instanceof Number
|
|
@@ -74,8 +109,8 @@ const signalHandler = {
|
|
|
74
109
|
notifySet(receiver, makeContext(property, { was: current, now: value } ) )
|
|
75
110
|
}
|
|
76
111
|
if (typeof current === 'undefined') {
|
|
77
|
-
notifySet(receiver, makeContext(
|
|
78
|
-
notifySet(receiver, makeContext(
|
|
112
|
+
notifySet(receiver, makeContext(DEP.ITERATE, {}))
|
|
113
|
+
notifySet(receiver, makeContext(DEP.LENGTH, {}))
|
|
79
114
|
}
|
|
80
115
|
return true
|
|
81
116
|
},
|
|
@@ -92,19 +127,21 @@ const signalHandler = {
|
|
|
92
127
|
delete target[property]
|
|
93
128
|
let receiver = signals.get(target) // receiver is not part of the trap arguments, so retrieve it here
|
|
94
129
|
notifySet(receiver, makeContext(property,{ delete: true, was: current }))
|
|
130
|
+
notifySet(receiver, makeContext(DEP.ITERATE, { delete: true, property })
|
|
131
|
+
)
|
|
95
132
|
}
|
|
96
133
|
return true
|
|
97
134
|
},
|
|
98
135
|
defineProperty: (target, property, descriptor) => {
|
|
99
136
|
if (typeof target[property] === 'undefined') {
|
|
100
137
|
let receiver = signals.get(target) // receiver is not part of the trap arguments, so retrieve it here
|
|
101
|
-
notifySet(receiver, makeContext(
|
|
138
|
+
notifySet(receiver, makeContext(DEP.ITERATE, {}))
|
|
102
139
|
}
|
|
103
140
|
return Object.defineProperty(target, property, descriptor)
|
|
104
141
|
},
|
|
105
142
|
ownKeys: (target) => {
|
|
106
143
|
let receiver = signals.get(target) // receiver is not part of the trap arguments, so retrieve it here
|
|
107
|
-
notifyGet(receiver,
|
|
144
|
+
notifyGet(receiver, DEP.ITERATE)
|
|
108
145
|
return Reflect.ownKeys(target)
|
|
109
146
|
}
|
|
110
147
|
|
|
@@ -122,11 +159,13 @@ export const signals = new WeakMap()
|
|
|
122
159
|
* Creates a new signal proxy of the given object, that intercepts get/has and set/delete
|
|
123
160
|
* to allow reactive functions to be triggered when signal values change.
|
|
124
161
|
*/
|
|
125
|
-
export function signal(v) {
|
|
126
|
-
if (
|
|
127
|
-
|
|
162
|
+
export function signal(v = {}) {
|
|
163
|
+
if (v === null || typeof v !== 'object' && typeof v !== 'function') {
|
|
164
|
+
throw new TypeError(
|
|
165
|
+
`simplyflow/state: signal() expects an object, array, Map, Set, class instance, or function; received ${typeof v}`
|
|
166
|
+
)
|
|
128
167
|
}
|
|
129
|
-
if (v[
|
|
168
|
+
if (v[DEP.SIGNAL]) { // there can be only one signal for any value
|
|
130
169
|
return v
|
|
131
170
|
}
|
|
132
171
|
if (!signals.has(v)) {
|
|
@@ -153,21 +192,30 @@ let tracing = false
|
|
|
153
192
|
* call the given function and then disable all tracers.
|
|
154
193
|
* @return void
|
|
155
194
|
*/
|
|
156
|
-
export function trace(
|
|
157
|
-
if (typeof
|
|
195
|
+
export function trace(target, prop) {
|
|
196
|
+
if (typeof target==='function') {
|
|
158
197
|
tracing = true
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
198
|
+
try {
|
|
199
|
+
return target()
|
|
200
|
+
} finally {
|
|
201
|
+
tracing = false
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (!target || !target[DEP.SIGNAL]) {
|
|
206
|
+
throw new TypeError(
|
|
207
|
+
'simplyflow/state: trace() expects either a function or a signal'
|
|
208
|
+
)
|
|
170
209
|
}
|
|
210
|
+
|
|
211
|
+
const listeners = getListeners(target, prop)
|
|
212
|
+
return listeners.map(listener => {
|
|
213
|
+
return {
|
|
214
|
+
effect: listener.effectType,
|
|
215
|
+
fn: listener.effectFunction,
|
|
216
|
+
signal: signals.get(listener.effectFunction)
|
|
217
|
+
}
|
|
218
|
+
})
|
|
171
219
|
}
|
|
172
220
|
|
|
173
221
|
/**
|
|
@@ -180,6 +228,9 @@ export function trace(signal, prop) {
|
|
|
180
228
|
* set: function(signal, context, listener)
|
|
181
229
|
*/
|
|
182
230
|
export function addTracer(tracer) {
|
|
231
|
+
if (!tracer || typeof tracer !== 'object') {
|
|
232
|
+
throw new TypeError('simplyflow/state: addTracer() expects a tracer object')
|
|
233
|
+
}
|
|
183
234
|
if (!tracer.get && !tracer.set) {
|
|
184
235
|
throw new Error('simply.state: addTracer: missing "get" or "set" property in tracer', tracer)
|
|
185
236
|
}
|
|
@@ -207,7 +258,14 @@ let batchMode = 0
|
|
|
207
258
|
* Triggers any reactor function that depends on this signal
|
|
208
259
|
* to re-compute its values
|
|
209
260
|
*/
|
|
210
|
-
export function notifySet(self, context=
|
|
261
|
+
export function notifySet(self, context = new Map()) {
|
|
262
|
+
if (!self || !self[DEP.SIGNAL]) {
|
|
263
|
+
throw new TypeError('simplyflow/state: notifySet() expects a signal as first argument')
|
|
264
|
+
}
|
|
265
|
+
if (!(context instanceof Map)) {
|
|
266
|
+
throw new TypeError('simplyflow/state: notifySet() expects context to be a Map; use makeContext()')
|
|
267
|
+
}
|
|
268
|
+
|
|
211
269
|
let listeners = []
|
|
212
270
|
context.forEach((change, property) => {
|
|
213
271
|
let propListeners = getListeners(self, property)
|
|
@@ -240,8 +298,14 @@ export function notifySet(self, context={}) {
|
|
|
240
298
|
|
|
241
299
|
export function makeContext(property, change) {
|
|
242
300
|
let context = new Map()
|
|
243
|
-
if (
|
|
244
|
-
|
|
301
|
+
if (property instanceof Map) {
|
|
302
|
+
property.forEach((change, prop) => {
|
|
303
|
+
context.set(prop, change)
|
|
304
|
+
})
|
|
305
|
+
return context
|
|
306
|
+
}
|
|
307
|
+
if (property !== null && typeof property === 'object') {
|
|
308
|
+
for (const prop of Reflect.ownKeys(property)) {
|
|
245
309
|
context.set(prop, property[prop])
|
|
246
310
|
}
|
|
247
311
|
} else {
|
|
@@ -333,17 +397,22 @@ function setListeners(self, property, compute) {
|
|
|
333
397
|
* based on the current call (code path)
|
|
334
398
|
*/
|
|
335
399
|
function clearListeners(compute) {
|
|
336
|
-
|
|
337
|
-
if (connectedSignals) {
|
|
338
|
-
|
|
339
|
-
property.forEach(s => {
|
|
340
|
-
let listeners = listenersMap.get(s)
|
|
341
|
-
if (listeners.has(property)) {
|
|
342
|
-
listeners.get(property).delete(compute)
|
|
343
|
-
}
|
|
344
|
-
})
|
|
345
|
-
})
|
|
400
|
+
const connectedSignals = computeMap.get(compute)
|
|
401
|
+
if (!connectedSignals) {
|
|
402
|
+
return
|
|
346
403
|
}
|
|
404
|
+
|
|
405
|
+
connectedSignals.forEach((signals, property) => {
|
|
406
|
+
signals.forEach(signal => {
|
|
407
|
+
const listeners = listenersMap.get(signal)
|
|
408
|
+
|
|
409
|
+
if (listeners?.has(property)) {
|
|
410
|
+
listeners.get(property).delete(compute)
|
|
411
|
+
}
|
|
412
|
+
})
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
computeMap.delete(compute)
|
|
347
416
|
}
|
|
348
417
|
|
|
349
418
|
/**
|
|
@@ -367,11 +436,17 @@ const effectMap = new WeakMap()
|
|
|
367
436
|
*/
|
|
368
437
|
const signalStack = []
|
|
369
438
|
|
|
439
|
+
function assertFunction(fn, name) {
|
|
440
|
+
if (typeof fn !== 'function') {
|
|
441
|
+
throw new TypeError(`simplyflow/state: ${name}() expects a function`)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
370
444
|
/**
|
|
371
445
|
* Runs the given function at once, and then whenever a signal changes that
|
|
372
446
|
* is used by the given function (or at least signals used in the previous run).
|
|
373
447
|
*/
|
|
374
448
|
export function effect(fn) {
|
|
449
|
+
assertFunction(fn, 'effect')
|
|
375
450
|
if (effectStack.findIndex(f => fn==f)!==-1) {
|
|
376
451
|
throw new Error('Recursive update() call', {cause:fn})
|
|
377
452
|
}
|
|
@@ -427,8 +502,11 @@ export function effect(fn) {
|
|
|
427
502
|
|
|
428
503
|
|
|
429
504
|
export function destroy(connectedSignal) {
|
|
505
|
+
if (!connectedSignal || !connectedSignal[DEP.SIGNAL]) {
|
|
506
|
+
throw new TypeError('simplyflow/state: destroy() expects an effect signal')
|
|
507
|
+
}
|
|
430
508
|
// find the computeEffect associated with this signal
|
|
431
|
-
const computeEffect = effectMap.get(connectedSignal)
|
|
509
|
+
const computeEffect = effectMap.get(connectedSignal)
|
|
432
510
|
if (!computeEffect) {
|
|
433
511
|
return
|
|
434
512
|
}
|
|
@@ -437,11 +515,11 @@ export function destroy(connectedSignal) {
|
|
|
437
515
|
clearListeners(computeEffect)
|
|
438
516
|
|
|
439
517
|
// remove all references to connectedSignal
|
|
440
|
-
|
|
441
|
-
|
|
518
|
+
if (computeEffect.fn) {
|
|
519
|
+
signals.delete(computeEffect.fn)
|
|
520
|
+
}
|
|
442
521
|
|
|
443
522
|
effectMap.delete(connectedSignal)
|
|
444
|
-
|
|
445
523
|
// if no other references to connectedSignal exist, it will be garbage collected
|
|
446
524
|
}
|
|
447
525
|
|
|
@@ -454,6 +532,7 @@ export function destroy(connectedSignal) {
|
|
|
454
532
|
* @result mixed the result of the fn() function call
|
|
455
533
|
*/
|
|
456
534
|
export function batch(fn) {
|
|
535
|
+
assertFunction(fn, 'batch')
|
|
457
536
|
batchMode++
|
|
458
537
|
let result
|
|
459
538
|
try {
|
|
@@ -496,6 +575,12 @@ function runBatchedListeners() {
|
|
|
496
575
|
* @returns signal with the result of the effect function fn
|
|
497
576
|
*/
|
|
498
577
|
export function throttledEffect(fn, throttleTime) {
|
|
578
|
+
assertFunction(fn, 'throttledEffect')
|
|
579
|
+
if (!Number.isFinite(throttleTime) || throttleTime < 0) {
|
|
580
|
+
throw new TypeError(
|
|
581
|
+
`simplyflow/state: throttledEffect() expects throttleTime to be a non-negative number`
|
|
582
|
+
)
|
|
583
|
+
}
|
|
499
584
|
if (effectStack.findIndex(f => fn==f)!==-1) {
|
|
500
585
|
throw new Error('Recursive update() call', {cause:fn})
|
|
501
586
|
}
|
|
@@ -509,18 +594,41 @@ export function throttledEffect(fn, throttleTime) {
|
|
|
509
594
|
signals.set(fn, connectedSignal)
|
|
510
595
|
}
|
|
511
596
|
|
|
512
|
-
let
|
|
597
|
+
let throttledUntil = 0
|
|
513
598
|
let hasChange = true
|
|
599
|
+
let timeout = null
|
|
600
|
+
|
|
601
|
+
function schedule() {
|
|
602
|
+
if (timeout) {
|
|
603
|
+
return
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const delay = Math.max(0, throttledUntil - Date.now())
|
|
607
|
+
|
|
608
|
+
timeout = globalThis.setTimeout(() => {
|
|
609
|
+
timeout = null
|
|
610
|
+
|
|
611
|
+
if (hasChange) {
|
|
612
|
+
computeEffect()
|
|
613
|
+
}
|
|
614
|
+
}, delay)
|
|
615
|
+
}
|
|
616
|
+
|
|
514
617
|
// this is the function that is called automatically
|
|
515
618
|
// whenever a signal dependency changes
|
|
516
619
|
const computeEffect = function computeEffect() {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
if (throttled && throttled>Date.now()) {
|
|
620
|
+
const now = Date.now()
|
|
621
|
+
|
|
622
|
+
if (throttledUntil > now) {
|
|
521
623
|
hasChange = true
|
|
624
|
+
schedule()
|
|
522
625
|
return
|
|
523
626
|
}
|
|
627
|
+
|
|
628
|
+
if (signalStack.findIndex(s => s==connectedSignal)!==-1) {
|
|
629
|
+
throw new Error('Cyclical dependency in update() call', { cause: fn})
|
|
630
|
+
}
|
|
631
|
+
|
|
524
632
|
// remove all dependencies (signals) from previous runs
|
|
525
633
|
clearListeners(computeEffect)
|
|
526
634
|
// record new dependencies on this run
|
|
@@ -547,12 +655,8 @@ export function throttledEffect(fn, throttleTime) {
|
|
|
547
655
|
connectedSignal.current = result
|
|
548
656
|
}
|
|
549
657
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
if (hasChange) {
|
|
553
|
-
computeEffect()
|
|
554
|
-
}
|
|
555
|
-
}, throttleTime)
|
|
658
|
+
throttledUntil = Date.now()+throttleTime
|
|
659
|
+
schedule()
|
|
556
660
|
}
|
|
557
661
|
// run the computEffect immediately upon creation
|
|
558
662
|
computeEffect()
|
|
@@ -565,6 +669,12 @@ export function throttledEffect(fn, throttleTime) {
|
|
|
565
669
|
// on clock.tick() (or clock.time++) run only the clock.needsUpdate effects
|
|
566
670
|
// (first create a copy and reset clock.needsUpdate, then run effects)
|
|
567
671
|
export function clockEffect(fn, clock) {
|
|
672
|
+
assertFunction(fn, 'clockEffect')
|
|
673
|
+
if (!clock || typeof clock !== 'object' || typeof clock.time !== 'number') {
|
|
674
|
+
throw new TypeError(
|
|
675
|
+
`simplyflow/state: clockEffect() expects a clock object with a numeric .time property`
|
|
676
|
+
)
|
|
677
|
+
}
|
|
568
678
|
let connectedSignal = signals.get(fn)
|
|
569
679
|
if (!connectedSignal) {
|
|
570
680
|
connectedSignal = signal({
|
|
@@ -623,6 +733,7 @@ export function clockEffect(fn, clock) {
|
|
|
623
733
|
* @result mixed
|
|
624
734
|
*/
|
|
625
735
|
export function untracked(fn) {
|
|
736
|
+
assertFunction(fn, 'untracked')
|
|
626
737
|
const pos = computeStack.length-1
|
|
627
738
|
const remember = computeStack[pos]
|
|
628
739
|
computeStack[pos] = false
|
|
@@ -635,7 +746,6 @@ export function untracked(fn) {
|
|
|
635
746
|
|
|
636
747
|
/**
|
|
637
748
|
* This function will created a copy of the input, recursive if deep==true
|
|
638
|
-
* It will replace any non-clonable values with null
|
|
639
749
|
* It will replace signals with a clone of their target
|
|
640
750
|
* It will keep cyclical references intact
|
|
641
751
|
* @param value Object
|
|
@@ -655,16 +765,16 @@ export function clone(value, deep=false)
|
|
|
655
765
|
return value
|
|
656
766
|
}
|
|
657
767
|
if (Array.isArray(value)) {
|
|
658
|
-
|
|
768
|
+
const result = []
|
|
659
769
|
if (!deep) {
|
|
660
|
-
|
|
661
|
-
seen.set(value, result)
|
|
662
|
-
return result
|
|
770
|
+
return value.slice()
|
|
663
771
|
}
|
|
772
|
+
|
|
664
773
|
seen.set(value, result)
|
|
665
|
-
for (
|
|
666
|
-
result[
|
|
774
|
+
for (let i=0; i<value.length; i++) {
|
|
775
|
+
result[i] = innerClone(value[i])
|
|
667
776
|
}
|
|
777
|
+
return result
|
|
668
778
|
} else if (!value.constructor || value.constructor===Object) {
|
|
669
779
|
let result = {}
|
|
670
780
|
if (!value.constructor) {
|
|
@@ -681,7 +791,7 @@ export function clone(value, deep=false)
|
|
|
681
791
|
}
|
|
682
792
|
break
|
|
683
793
|
default:
|
|
684
|
-
return
|
|
794
|
+
return value // primitive
|
|
685
795
|
break
|
|
686
796
|
}
|
|
687
797
|
}
|
package/src/symbols.mjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const DEP = {
|
|
2
|
+
ITERATE: Symbol.for('@simplyedit/simplyflow.iterate'),
|
|
3
|
+
XRAY: Symbol.for('@simplyedit/simplyflow.xRay'),
|
|
4
|
+
SIGNAL: Symbol.for('@simplyedit/simplyflow.Signal'),
|
|
5
|
+
TEMPLATE: Symbol.for('@simplyedit/simplyflow.bindTemplate'),
|
|
6
|
+
LENGTH: 'length',
|
|
7
|
+
SIZE: 'size'
|
|
8
|
+
}
|