effect-start 0.25.0 → 0.26.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.
Files changed (117) hide show
  1. package/package.json +18 -86
  2. package/dist/ChildProcess.js +0 -42
  3. package/dist/Commander.js +0 -410
  4. package/dist/ContentNegotiation.js +0 -465
  5. package/dist/Cookies.js +0 -371
  6. package/dist/Development.js +0 -94
  7. package/dist/Effectify.js +0 -27
  8. package/dist/Entity.js +0 -289
  9. package/dist/Fetch.js +0 -192
  10. package/dist/FilePathPattern.js +0 -97
  11. package/dist/FileRouter.js +0 -204
  12. package/dist/FileRouterCodegen.js +0 -298
  13. package/dist/FileSystem.js +0 -132
  14. package/dist/Http.js +0 -107
  15. package/dist/PathPattern.js +0 -451
  16. package/dist/PlatformError.js +0 -40
  17. package/dist/PlatformRuntime.js +0 -71
  18. package/dist/Route.js +0 -143
  19. package/dist/RouteBody.js +0 -92
  20. package/dist/RouteError.js +0 -76
  21. package/dist/RouteHook.js +0 -64
  22. package/dist/RouteHttp.js +0 -367
  23. package/dist/RouteHttpTracer.js +0 -90
  24. package/dist/RouteMount.js +0 -86
  25. package/dist/RouteSchema.js +0 -271
  26. package/dist/RouteSse.js +0 -94
  27. package/dist/RouteTree.js +0 -119
  28. package/dist/RouteTrie.js +0 -179
  29. package/dist/SchemaExtra.js +0 -99
  30. package/dist/Socket.js +0 -40
  31. package/dist/SqlIntrospect.js +0 -515
  32. package/dist/Start.js +0 -79
  33. package/dist/StartApp.js +0 -3
  34. package/dist/StreamExtra.js +0 -135
  35. package/dist/System.js +0 -38
  36. package/dist/TuplePathPattern.js +0 -74
  37. package/dist/Unique.js +0 -226
  38. package/dist/Values.js +0 -52
  39. package/dist/bun/BunBundle.js +0 -186
  40. package/dist/bun/BunChildProcessSpawner.js +0 -142
  41. package/dist/bun/BunImportTrackerPlugin.js +0 -91
  42. package/dist/bun/BunRoute.js +0 -157
  43. package/dist/bun/BunRuntime.js +0 -41
  44. package/dist/bun/BunServer.js +0 -285
  45. package/dist/bun/BunVirtualFilesPlugin.js +0 -54
  46. package/dist/bun/_BunEnhancedResolve.js +0 -127
  47. package/dist/bun/index.js +0 -5
  48. package/dist/bundler/Bundle.js +0 -92
  49. package/dist/bundler/BundleFiles.js +0 -154
  50. package/dist/bundler/BundleRoute.js +0 -62
  51. package/dist/client/Overlay.js +0 -33
  52. package/dist/client/ScrollState.js +0 -106
  53. package/dist/client/index.js +0 -97
  54. package/dist/console/Console.js +0 -42
  55. package/dist/console/ConsoleErrors.js +0 -211
  56. package/dist/console/ConsoleLogger.js +0 -56
  57. package/dist/console/ConsoleMetrics.js +0 -72
  58. package/dist/console/ConsoleProcess.js +0 -59
  59. package/dist/console/ConsoleStore.js +0 -72
  60. package/dist/console/ConsoleTracer.js +0 -107
  61. package/dist/console/Simulation.js +0 -784
  62. package/dist/console/index.js +0 -3
  63. package/dist/console/routes/tree.js +0 -30
  64. package/dist/datastar/actions/fetch.js +0 -536
  65. package/dist/datastar/actions/peek.js +0 -13
  66. package/dist/datastar/actions/setAll.js +0 -19
  67. package/dist/datastar/actions/toggleAll.js +0 -19
  68. package/dist/datastar/attributes/attr.js +0 -49
  69. package/dist/datastar/attributes/bind.js +0 -194
  70. package/dist/datastar/attributes/class.js +0 -54
  71. package/dist/datastar/attributes/computed.js +0 -25
  72. package/dist/datastar/attributes/effect.js +0 -10
  73. package/dist/datastar/attributes/indicator.js +0 -33
  74. package/dist/datastar/attributes/init.js +0 -27
  75. package/dist/datastar/attributes/jsonSignals.js +0 -33
  76. package/dist/datastar/attributes/on.js +0 -81
  77. package/dist/datastar/attributes/onIntersect.js +0 -53
  78. package/dist/datastar/attributes/onInterval.js +0 -31
  79. package/dist/datastar/attributes/onSignalPatch.js +0 -51
  80. package/dist/datastar/attributes/ref.js +0 -11
  81. package/dist/datastar/attributes/show.js +0 -32
  82. package/dist/datastar/attributes/signals.js +0 -18
  83. package/dist/datastar/attributes/style.js +0 -57
  84. package/dist/datastar/attributes/text.js +0 -29
  85. package/dist/datastar/engine.js +0 -1145
  86. package/dist/datastar/index.js +0 -25
  87. package/dist/datastar/utils.js +0 -250
  88. package/dist/datastar/watchers/patchElements.js +0 -486
  89. package/dist/datastar/watchers/patchSignals.js +0 -14
  90. package/dist/experimental/EncryptedCookies.js +0 -328
  91. package/dist/experimental/index.js +0 -1
  92. package/dist/hyper/Hyper.js +0 -28
  93. package/dist/hyper/HyperHtml.js +0 -165
  94. package/dist/hyper/HyperNode.js +0 -13
  95. package/dist/hyper/HyperRoute.js +0 -45
  96. package/dist/hyper/html.js +0 -30
  97. package/dist/hyper/index.js +0 -5
  98. package/dist/hyper/jsx-runtime.js +0 -14
  99. package/dist/index.js +0 -8
  100. package/dist/node/NodeFileSystem.js +0 -675
  101. package/dist/node/NodeUtils.js +0 -23
  102. package/dist/sql/Sql.js +0 -8
  103. package/dist/sql/bun/index.js +0 -142
  104. package/dist/sql/index.js +0 -1
  105. package/dist/sql/libsql/index.js +0 -156
  106. package/dist/sql/mssql/docker.js +0 -110
  107. package/dist/sql/mssql/index.js +0 -194
  108. package/dist/testing/TestLogger.js +0 -42
  109. package/dist/testing/index.js +0 -2
  110. package/dist/testing/utils.js +0 -61
  111. package/dist/x/cloudflare/CloudflareTunnel.js +0 -63
  112. package/dist/x/cloudflare/index.js +0 -1
  113. package/dist/x/tailscale/TailscaleTunnel.js +0 -94
  114. package/dist/x/tailscale/index.js +0 -1
  115. package/dist/x/tailwind/TailwindPlugin.js +0 -294
  116. package/dist/x/tailwind/compile.js +0 -210
  117. package/dist/x/tailwind/plugin.js +0 -17
@@ -1,1145 +0,0 @@
1
- import { aliasify, hasOwn, isHTMLOrSVG, isPojo, pathToObj, snake } from "./utils.js"
2
-
3
- /*********
4
- * consts.ts
5
- *********/
6
- const lol = /🖕JS_DS🚀/.source
7
- export const DSP = lol.slice(0, 5)
8
- export const DSS = lol.slice(4)
9
- export const DATASTAR_FETCH_EVENT = "datastar-fetch"
10
- export const DATASTAR_SIGNAL_PATCH_EVENT = "datastar-signal-patch"
11
-
12
- /*********
13
- * types.ts
14
- *********/
15
-
16
- /*********
17
- * signals.ts
18
- *********/
19
-
20
- const ReactiveFlags = /** @type {const} */ {
21
- None: 0,
22
- Mutable: 1 << 0,
23
- Watching: 1 << 1,
24
- RecursedCheck: 1 << 2,
25
- Recursed: 1 << 3,
26
- Dirty: 1 << 4,
27
- Pending: 1 << 5,
28
- }
29
-
30
- const EffectFlags = /** @type {const} */ {
31
- Queued: 1 << 6,
32
- }
33
-
34
- const currentPatch = []
35
- const queuedEffects = []
36
- let batchDepth = 0
37
- let notifyIndex = 0
38
- let queuedEffectsLength = 0
39
- let prevSub
40
- let activeSub
41
- let version = 0
42
-
43
- export const beginBatch = () => {
44
- batchDepth++
45
- }
46
-
47
- export const endBatch = () => {
48
- if (!--batchDepth) {
49
- flush()
50
- dispatch()
51
- }
52
- }
53
-
54
- export const startPeeking = (sub) => {
55
- prevSub = activeSub
56
- activeSub = sub
57
- }
58
-
59
- export const stopPeeking = () => {
60
- activeSub = prevSub
61
- prevSub = undefined
62
- }
63
-
64
- export const signal = (initialValue) => {
65
- return signalOper.bind(0, {
66
- previousValue: initialValue,
67
- value_: initialValue,
68
- flags_: 1,
69
- })
70
- }
71
-
72
- const computedSymbol = Symbol("computed")
73
- export const computed = (getter) => {
74
- const c = computedOper.bind(0, {
75
- flags_: 17,
76
- getter,
77
- })
78
- // @ts-ignore
79
- c[computedSymbol] = 1
80
- return c
81
- }
82
-
83
- export const effect = (fn) => {
84
- const e = {
85
- fn_: fn,
86
- flags_: 2,
87
- }
88
- if (activeSub) {
89
- link(e, activeSub)
90
- }
91
- startPeeking(e)
92
- beginBatch()
93
- try {
94
- e.fn_()
95
- } finally {
96
- endBatch()
97
- stopPeeking()
98
- }
99
- return effectOper.bind(0, e)
100
- }
101
-
102
- const flush = () => {
103
- while (notifyIndex < queuedEffectsLength) {
104
- const effect = queuedEffects[notifyIndex]
105
- queuedEffects[notifyIndex++] = undefined
106
- run(effect, (effect.flags_ &= ~EffectFlags.Queued))
107
- }
108
- notifyIndex = 0
109
- queuedEffectsLength = 0
110
- }
111
-
112
- const update = (signal) => {
113
- if ("getter" in signal) {
114
- return updateComputed(signal)
115
- }
116
- return updateSignal(signal, signal.value_)
117
- }
118
-
119
- const updateComputed = (c) => {
120
- startPeeking(c)
121
- startTracking(c)
122
- try {
123
- const oldValue = c.value_
124
- return oldValue !== (c.value_ = c.getter(oldValue))
125
- } finally {
126
- stopPeeking()
127
- endTracking(c)
128
- }
129
- }
130
-
131
- const updateSignal = (s, value) => {
132
- s.flags_ = 1
133
- return s.previousValue !== (s.previousValue = value)
134
- }
135
-
136
- const notify = (e) => {
137
- const flags = e.flags_
138
- if (!(flags & EffectFlags.Queued)) {
139
- e.flags_ = flags | EffectFlags.Queued
140
- const subs = e.subs_
141
- if (subs) {
142
- notify(subs.sub_)
143
- } else {
144
- queuedEffects[queuedEffectsLength++] = e
145
- }
146
- }
147
- }
148
-
149
- const run = (e, flags) => {
150
- if (
151
- flags & (16) ||
152
- (flags & (32) && checkDirty(e.deps_, e))
153
- ) {
154
- startPeeking(e)
155
- startTracking(e)
156
- beginBatch()
157
- try {
158
- e.fn_()
159
- } finally {
160
- endBatch()
161
- stopPeeking()
162
- endTracking(e)
163
- }
164
- return
165
- }
166
- if (flags & (32)) {
167
- e.flags_ = flags & ~(32)
168
- }
169
- let link = e.deps_
170
- while (link) {
171
- const dep = link.dep_
172
- const depFlags = dep.flags_
173
- if (depFlags & EffectFlags.Queued) {
174
- run(dep, (dep.flags_ = depFlags & ~EffectFlags.Queued))
175
- }
176
- link = link.nextDep_
177
- }
178
- }
179
-
180
- const signalOper = (s, ...value) => {
181
- if (value.length) {
182
- if (s.value_ !== (s.value_ = value[0])) {
183
- s.flags_ = 17
184
- const subs = s.subs_
185
- if (subs) {
186
- propagate(subs)
187
- if (!batchDepth) {
188
- flush()
189
- }
190
- }
191
- return true
192
- }
193
- return false
194
- }
195
- const currentValue = s.value_
196
- if (s.flags_ & (16)) {
197
- if (updateSignal(s, currentValue)) {
198
- const subs_ = s.subs_
199
- if (subs_) {
200
- shallowPropagate(subs_)
201
- }
202
- }
203
- }
204
- if (activeSub) {
205
- link(s, activeSub)
206
- }
207
- return currentValue
208
- }
209
-
210
- const computedOper = (c) => {
211
- const flags = c.flags_
212
- if (
213
- flags & (16) ||
214
- (flags & (32) && checkDirty(c.deps_, c))
215
- ) {
216
- if (updateComputed(c)) {
217
- const subs = c.subs_
218
- if (subs) {
219
- shallowPropagate(subs)
220
- }
221
- }
222
- } else if (flags & (32)) {
223
- c.flags_ = flags & ~(32)
224
- }
225
- if (activeSub) {
226
- link(c, activeSub)
227
- }
228
- return c.value_
229
- }
230
-
231
- const effectOper = (e) => {
232
- let dep = e.deps_
233
- while (dep) {
234
- dep = unlink(dep, e)
235
- }
236
- const sub = e.subs_
237
- if (sub) {
238
- unlink(sub)
239
- }
240
- e.flags_ = 0
241
- }
242
-
243
- const link = (dep, sub) => {
244
- const prevDep = sub.depsTail_
245
- if (prevDep && prevDep.dep_ === dep) {
246
- return
247
- }
248
- const nextDep = prevDep ? prevDep.nextDep_ : sub.deps_
249
- if (nextDep && nextDep.dep_ === dep) {
250
- nextDep.version_ = version
251
- sub.depsTail_ = nextDep
252
- return
253
- }
254
- const prevSub = dep.subsTail_
255
- if (prevSub && prevSub.version_ === version && prevSub.sub_ === sub) {
256
- return
257
- }
258
- const newLink =
259
- (sub.depsTail_ =
260
- dep.subsTail_ =
261
- {
262
- version_: version,
263
- dep_: dep,
264
- sub_: sub,
265
- prevDep_: prevDep,
266
- nextDep_: nextDep,
267
- prevSub_: prevSub,
268
- })
269
- if (nextDep) {
270
- nextDep.prevDep_ = newLink
271
- }
272
- if (prevDep) {
273
- prevDep.nextDep_ = newLink
274
- } else {
275
- sub.deps_ = newLink
276
- }
277
- if (prevSub) {
278
- prevSub.nextSub_ = newLink
279
- } else {
280
- dep.subs_ = newLink
281
- }
282
- }
283
-
284
- const unlink = (link, sub = link.sub_) => {
285
- const dep_ = link.dep_
286
- const prevDep_ = link.prevDep_
287
- const nextDep_ = link.nextDep_
288
- const nextSub_ = link.nextSub_
289
- const prevSub_ = link.prevSub_
290
- if (nextDep_) {
291
- nextDep_.prevDep_ = prevDep_
292
- } else {
293
- sub.depsTail_ = prevDep_
294
- }
295
- if (prevDep_) {
296
- prevDep_.nextDep_ = nextDep_
297
- } else {
298
- sub.deps_ = nextDep_
299
- }
300
- if (nextSub_) {
301
- nextSub_.prevSub_ = prevSub_
302
- } else {
303
- dep_.subsTail_ = prevSub_
304
- }
305
- if (prevSub_) {
306
- prevSub_.nextSub_ = nextSub_
307
- } else if (!(dep_.subs_ = nextSub_)) {
308
- if ("getter" in dep_) {
309
- let toRemove = dep_.deps_
310
- if (toRemove) {
311
- dep_.flags_ = 17
312
- do {
313
- toRemove = unlink(toRemove, dep_)
314
- } while (toRemove)
315
- }
316
- } else if (!("previousValue" in dep_)) {
317
- effectOper(dep_)
318
- }
319
- }
320
- return nextDep_
321
- }
322
-
323
- const propagate = (link) => {
324
- let next = link.nextSub_
325
- let stack
326
-
327
- top: while (true) {
328
- const sub = link.sub_
329
-
330
- let flags = sub.flags_
331
-
332
- if (
333
- !(
334
- flags &
335
- (60)
336
- )
337
- ) {
338
- sub.flags_ = flags | (32)
339
- } else if (!(flags & (12))) {
340
- flags = 0
341
- } else if (!(flags & (4))) {
342
- sub.flags_ =
343
- (flags & ~(8)) | (32)
344
- } else if (
345
- !(flags & (48)) &&
346
- isValidLink(link, sub)
347
- ) {
348
- sub.flags_ = flags | (40)
349
- flags &= 1
350
- } else {
351
- flags = 0
352
- }
353
-
354
- if (flags & (2)) {
355
- notify(sub)
356
- }
357
-
358
- if (flags & (1)) {
359
- const subSubs = sub.subs_
360
- if (subSubs) {
361
- const nextSub = (link = subSubs).nextSub_
362
- if (nextSub) {
363
- stack = { value_: next, prev_: stack }
364
- next = nextSub
365
- }
366
- continue
367
- }
368
- }
369
-
370
- if ((link = next)) {
371
- next = link.nextSub_
372
- continue
373
- }
374
-
375
- while (stack) {
376
- link = stack.value_
377
- stack = stack.prev_
378
- if (link) {
379
- next = link.nextSub_
380
- continue top
381
- }
382
- }
383
-
384
- break
385
- }
386
- }
387
-
388
- const startTracking = (sub) => {
389
- version++
390
- sub.depsTail_ = undefined
391
- sub.flags_ =
392
- (sub.flags_ & ~(56)) |
393
- (4)
394
- }
395
-
396
- const endTracking = (sub) => {
397
- const depsTail_ = sub.depsTail_
398
- let toRemove = depsTail_ ? depsTail_.nextDep_ : sub.deps_
399
- while (toRemove) {
400
- toRemove = unlink(toRemove, sub)
401
- }
402
- sub.flags_ &= ~(4)
403
- }
404
-
405
- const checkDirty = (link, sub) => {
406
- let stack
407
- let checkDepth = 0
408
- let dirty = false
409
-
410
- top: while (true) {
411
- const dep = link.dep_
412
- const flags = dep.flags_
413
-
414
- if (sub.flags_ & (16)) {
415
- dirty = true
416
- } else if (
417
- (flags & (17)) ===
418
- (17)
419
- ) {
420
- if (update(dep)) {
421
- const subs = dep.subs_
422
- if (subs.nextSub_) {
423
- shallowPropagate(subs)
424
- }
425
- dirty = true
426
- }
427
- } else if (
428
- (flags & (33)) ===
429
- (33)
430
- ) {
431
- if (link.nextSub_ || link.prevSub_) {
432
- stack = { value_: link, prev_: stack }
433
- }
434
- link = dep.deps_
435
- sub = dep
436
- ++checkDepth
437
- continue
438
- }
439
-
440
- if (!dirty) {
441
- const nextDep = link.nextDep_
442
- if (nextDep) {
443
- link = nextDep
444
- continue
445
- }
446
- }
447
-
448
- while (checkDepth--) {
449
- const firstSub = sub.subs_
450
- const hasMultipleSubs = firstSub.nextSub_
451
- if (hasMultipleSubs) {
452
- link = stack.value_
453
- stack = stack.prev_
454
- } else {
455
- link = firstSub
456
- }
457
- if (dirty) {
458
- if (update(sub)) {
459
- if (hasMultipleSubs) {
460
- shallowPropagate(firstSub)
461
- }
462
- sub = link.sub_
463
- continue
464
- }
465
- dirty = false
466
- } else {
467
- sub.flags_ &= ~(32)
468
- }
469
- sub = link.sub_
470
- if (link.nextDep_) {
471
- link = link.nextDep_
472
- continue top
473
- }
474
- }
475
-
476
- return dirty
477
- }
478
- }
479
-
480
- const shallowPropagate = (link) => {
481
- do {
482
- const sub = link.sub_
483
- const flags = sub.flags_
484
- if (
485
- (flags & (48)) ===
486
- (32)
487
- ) {
488
- sub.flags_ = flags | (16)
489
- if (flags & (2)) {
490
- notify(sub)
491
- }
492
- }
493
- } while ((link = link.nextSub_))
494
- }
495
-
496
- const isValidLink = (checkLink, sub) => {
497
- let link = sub.depsTail_
498
- while (link) {
499
- if (link === checkLink) {
500
- return true
501
- }
502
- link = link.prevDep_
503
- }
504
- return false
505
- }
506
-
507
- export const getPath = (path) => {
508
- let result = root
509
- const split = path.split(".")
510
- for (const path of split) {
511
- if (result == null || !hasOwn(result, path)) {
512
- return
513
- }
514
- result = result[path]
515
- }
516
- return result
517
- }
518
-
519
- const deep = (value, prefix = "") => {
520
- const isArr = Array.isArray(value)
521
- if (isArr || isPojo(value)) {
522
- const deepObj = (isArr ? [] : {})
523
- for (const key in value) {
524
- deepObj[key] = signal(deep((value)[key], `${prefix + key}.`))
525
- }
526
- const keys = signal(0)
527
- return new Proxy(deepObj, {
528
- get(_, prop) {
529
- if (!(prop === "toJSON" && !hasOwn(deepObj, prop))) {
530
- if (isArr && prop in Array.prototype) {
531
- keys()
532
- return deepObj[prop]
533
- }
534
- if (typeof prop === "symbol") {
535
- return deepObj[prop]
536
- }
537
- if (!hasOwn(deepObj, prop) || deepObj[prop]() == null) {
538
- deepObj[prop] = signal("")
539
- dispatch(prefix + prop, "")
540
- keys(keys() + 1)
541
- }
542
- return deepObj[prop]()
543
- }
544
- },
545
- set(_, prop, newValue) {
546
- const path = prefix + prop
547
- if (isArr && prop === "length") {
548
- const diff = (deepObj[prop]) - newValue
549
- deepObj[prop] = newValue
550
- if (diff > 0) {
551
- const patch = {}
552
- for (let i = newValue; i < deepObj[prop]; i++) {
553
- patch[i] = null
554
- }
555
- dispatch(prefix.slice(0, -1), patch)
556
- keys(keys() + 1)
557
- }
558
- } else if (hasOwn(deepObj, prop)) {
559
- if (newValue == null) {
560
- delete deepObj[prop]
561
- } else if (hasOwn(newValue, computedSymbol)) {
562
- deepObj[prop] = newValue
563
- dispatch(path, "")
564
- } else {
565
- const currentValue = deepObj[prop]()
566
- const pathStr = `${path}.`
567
- if (isPojo(currentValue) && isPojo(newValue)) {
568
- for (const key in currentValue) {
569
- if (!hasOwn(newValue, key)) {
570
- delete currentValue[key]
571
- dispatch(pathStr + key, null)
572
- }
573
- }
574
- for (const key in newValue) {
575
- const nextVal = newValue[key]
576
- if (currentValue[key] !== nextVal) {
577
- currentValue[key] = nextVal
578
- }
579
- }
580
- } else if (deepObj[prop](deep(newValue, pathStr))) {
581
- dispatch(path, newValue)
582
- }
583
- }
584
- } else if (newValue != null) {
585
- if (hasOwn(newValue, computedSymbol)) {
586
- deepObj[prop] = newValue
587
- dispatch(path, "")
588
- } else {
589
- deepObj[prop] = signal(deep(newValue, `${path}.`))
590
- dispatch(path, newValue)
591
- }
592
- keys(keys() + 1)
593
- }
594
-
595
- return true
596
- },
597
- deleteProperty(_, prop) {
598
- delete deepObj[prop]
599
- keys(keys() + 1)
600
- return true
601
- },
602
- ownKeys() {
603
- keys()
604
- return Reflect.ownKeys(deepObj)
605
- },
606
- has(_, prop) {
607
- keys()
608
- return prop in deepObj
609
- },
610
- })
611
- }
612
- return value
613
- }
614
-
615
- const dispatch = (path, value) => {
616
- if (path !== undefined && value !== undefined) {
617
- currentPatch.push([path, value])
618
- }
619
- if (!batchDepth && currentPatch.length) {
620
- const detail = pathToObj(currentPatch)
621
- currentPatch.length = 0
622
- document.dispatchEvent(
623
- new CustomEvent(DATASTAR_SIGNAL_PATCH_EVENT, {
624
- detail,
625
- }),
626
- )
627
- }
628
- }
629
-
630
- export const mergePatch = (patch, { ifMissing } = {}) => {
631
- beginBatch()
632
- for (const key in patch) {
633
- if (patch[key] == null) {
634
- if (!ifMissing) {
635
- delete root[key]
636
- }
637
- } else {
638
- mergeInner(patch[key], key, root, "", ifMissing)
639
- }
640
- }
641
- endBatch()
642
- }
643
-
644
- export const mergePaths = (paths, options) =>
645
- mergePatch(pathToObj(paths), options)
646
-
647
- const mergeInner = (
648
- patch,
649
- target,
650
- targetParent,
651
- prefix,
652
- ifMissing,
653
- ) => {
654
- if (isPojo(patch)) {
655
- if (
656
- !(
657
- hasOwn(targetParent, target) &&
658
- (isPojo(targetParent[target]) || Array.isArray(targetParent[target]))
659
- )
660
- ) {
661
- targetParent[target] = {}
662
- }
663
-
664
- for (const key in patch) {
665
- if (patch[key] == null) {
666
- if (!ifMissing) {
667
- delete targetParent[target][key]
668
- }
669
- } else {
670
- mergeInner(patch[key], key, targetParent[target], `${prefix + target}.`, ifMissing)
671
- }
672
- }
673
- } else if (!(ifMissing && hasOwn(targetParent, target))) {
674
- targetParent[target] = patch
675
- }
676
- }
677
-
678
- const toRegExp = (val) =>
679
- typeof val === "string" ? RegExp(val.replace(/^\/|\/$/g, "")) : val
680
-
681
- export const filtered = (
682
- { include = /.*/, exclude = /(?!)/ } = {},
683
- obj = root,
684
- ) => {
685
- const includeRe = toRegExp(include)
686
- const excludeRe = toRegExp(exclude)
687
- const paths = []
688
- const stack = [[obj, ""]]
689
-
690
- while (stack.length) {
691
- const [node, prefix] = stack.pop()
692
-
693
- for (const key in node) {
694
- const path = prefix + key
695
- if (isPojo(node[key])) {
696
- stack.push([node[key], `${path}.`])
697
- } else if (includeRe.test(path) && !excludeRe.test(path)) {
698
- paths.push([path, getPath(path)])
699
- }
700
- }
701
- }
702
-
703
- return pathToObj(paths)
704
- }
705
-
706
- export const root = deep({})
707
-
708
- /*********
709
- * engine.ts (plugin system)
710
- *********/
711
- const url = "https://data-star.dev/errors"
712
-
713
- const error = (ctx, reason, metadata = {}) => {
714
- Object.assign(metadata, ctx)
715
- const e = new Error()
716
- const r = snake(reason)
717
- const q = new URLSearchParams({
718
- metadata: JSON.stringify(metadata),
719
- }).toString()
720
- const c = JSON.stringify(metadata, null, 2)
721
- e.message = `${reason}\nMore info: ${url}/${r}?${q}\nContext: ${c}`
722
- return e
723
- }
724
-
725
- const actionPlugins = new Map()
726
- const attributePlugins = new Map()
727
- const watcherPlugins = new Map()
728
-
729
- export const actions = new Proxy(
730
- {},
731
- {
732
- get: (_, prop) => actionPlugins.get(prop)?.apply,
733
- has: (_, prop) => actionPlugins.has(prop),
734
- ownKeys: () => Reflect.ownKeys(actionPlugins),
735
- set: () => false,
736
- deleteProperty: () => false,
737
- },
738
- )
739
-
740
- const removals = new Map()
741
-
742
- const queuedAttributes = []
743
- const queuedAttributeNames = new Set()
744
- const observedRoots = new WeakSet()
745
- export const attribute = (
746
- plugin,
747
- ) => {
748
- queuedAttributes.push(plugin)
749
-
750
- if (queuedAttributes.length === 1) {
751
- setTimeout(() => {
752
- for (const attribute of queuedAttributes) {
753
- queuedAttributeNames.add(attribute.name)
754
- attributePlugins.set(attribute.name, attribute)
755
- }
756
- queuedAttributes.length = 0
757
- apply()
758
- queuedAttributeNames.clear()
759
- })
760
- }
761
- }
762
-
763
- export const action = (plugin) => {
764
- actionPlugins.set(plugin.name, plugin)
765
- }
766
-
767
- document.addEventListener(DATASTAR_FETCH_EVENT, ((evt) => {
768
- const plugin = watcherPlugins.get(evt.detail.type)
769
- if (plugin) {
770
- plugin.apply(
771
- {
772
- error: error.bind(0, {
773
- plugin: { type: "watcher", name: plugin.name },
774
- element: {
775
- id: (evt.target).id,
776
- tag: (evt.target).tagName,
777
- },
778
- }),
779
- },
780
- evt.detail.argsRaw,
781
- )
782
- }
783
- }))
784
-
785
- export const watcher = (plugin) => {
786
- watcherPlugins.set(plugin.name, plugin)
787
- }
788
-
789
- const cleanupEls = (els) => {
790
- for (const el of els) {
791
- const elCleanups = removals.get(el)
792
- if (elCleanups && removals.delete(el)) {
793
- for (const attrCleanups of elCleanups.values()) {
794
- for (const cleanup of attrCleanups.values()) {
795
- cleanup()
796
- }
797
- }
798
- }
799
- }
800
- }
801
-
802
- const aliasedIgnore = aliasify("ignore")
803
- const aliasedIgnoreAttr = `[${aliasedIgnore}]`
804
- const shouldIgnore = (el) =>
805
- el.hasAttribute(`${aliasedIgnore}__self`) || !!el.closest(aliasedIgnoreAttr)
806
-
807
- const applyEls = (els, onlyNew) => {
808
- for (const el of els) {
809
- if (!shouldIgnore(el)) {
810
- for (const key in el.dataset) {
811
- applyAttributePlugin(
812
- el,
813
- key.replace(/[A-Z]/g, "-$&").toLowerCase(),
814
- el.dataset[key],
815
- onlyNew,
816
- )
817
- }
818
- }
819
- }
820
- }
821
-
822
- const observe = (mutations) => {
823
- for (const { target, type, attributeName, addedNodes, removedNodes } of mutations) {
824
- if (type === "childList") {
825
- for (const node of removedNodes) {
826
- if (isHTMLOrSVG(node)) {
827
- cleanupEls([node])
828
- cleanupEls(node.querySelectorAll("*"))
829
- }
830
- }
831
-
832
- for (const node of addedNodes) {
833
- if (isHTMLOrSVG(node)) {
834
- applyEls([node])
835
- applyEls(node.querySelectorAll("*"))
836
- }
837
- }
838
- } else if (
839
- type === "attributes" &&
840
- attributeName.startsWith("data-") &&
841
- isHTMLOrSVG(target) &&
842
- !shouldIgnore(target)
843
- ) {
844
- const key = attributeName.slice(5)
845
- const value = target.getAttribute(attributeName)
846
- if (value === null) {
847
- const elCleanups = removals.get(target)
848
- if (elCleanups) {
849
- const attrCleanups = elCleanups.get(key)
850
- if (attrCleanups) {
851
- for (const cleanup of attrCleanups.values()) {
852
- cleanup()
853
- }
854
- elCleanups.delete(key)
855
- }
856
- }
857
- } else {
858
- applyAttributePlugin(target, key, value)
859
- }
860
- }
861
- }
862
- }
863
-
864
- const mutationObserver = new MutationObserver(observe)
865
-
866
- export const parseAttributeKey = (
867
- rawKey,
868
- ) => {
869
- const [namePart, ...rawModifiers] = rawKey.split("__")
870
- const [pluginName, key] = namePart.split(/:(.+)/)
871
- const mods = new Map()
872
-
873
- for (const rawMod of rawModifiers) {
874
- const [label, ...mod] = rawMod.split(".")
875
- mods.set(label, new Set(mod))
876
- }
877
-
878
- return { pluginName, key, mods }
879
- }
880
-
881
- export const isDocumentObserverActive = () => observedRoots.has(document.documentElement)
882
-
883
- export const apply = (
884
- root = document.documentElement,
885
- observeRoot = true,
886
- ) => {
887
- if (isHTMLOrSVG(root)) {
888
- applyEls([root], true)
889
- }
890
- applyEls(root.querySelectorAll("*"), true)
891
-
892
- if (observeRoot) {
893
- mutationObserver.observe(root, {
894
- subtree: true,
895
- childList: true,
896
- attributes: true,
897
- })
898
- observedRoots.add(root)
899
- }
900
- }
901
-
902
- const applyAttributePlugin = (
903
- el,
904
- attrKey,
905
- value,
906
- onlyNew,
907
- ) => {
908
- const rawKey = attrKey
909
- const { pluginName, key, mods } = parseAttributeKey(rawKey)
910
- const plugin = attributePlugins.get(pluginName)
911
- if ((!onlyNew || queuedAttributeNames.has(pluginName)) && plugin) {
912
- const ctx = {
913
- el,
914
- rawKey,
915
- mods,
916
- error: error.bind(0, {
917
- plugin: { type: "attribute", name: plugin.name },
918
- element: { id: el.id, tag: el.tagName },
919
- expression: { rawKey, key, value },
920
- }),
921
- key,
922
- value,
923
- loadedPluginNames: {
924
- actions: new Set(actionPlugins.keys()),
925
- attributes: new Set(attributePlugins.keys()),
926
- },
927
- rx: undefined,
928
- }
929
-
930
- const keyReq =
931
- (plugin.requirement &&
932
- (typeof plugin.requirement === "string" ? plugin.requirement : plugin.requirement.key)) ||
933
- "allowed"
934
- const valueReq =
935
- (plugin.requirement &&
936
- (typeof plugin.requirement === "string" ? plugin.requirement : plugin.requirement.value)) ||
937
- "allowed"
938
-
939
- const keyProvided = key !== undefined && key !== null && key !== ""
940
- const valueProvided = value !== undefined && value !== null && value !== ""
941
-
942
- if (keyProvided) {
943
- if (keyReq === "denied") {
944
- throw ctx.error("KeyNotAllowed")
945
- }
946
- } else if (keyReq === "must") {
947
- throw ctx.error("KeyRequired")
948
- }
949
-
950
- if (valueProvided) {
951
- if (valueReq === "denied") {
952
- throw ctx.error("ValueNotAllowed")
953
- }
954
- } else if (valueReq === "must") {
955
- throw ctx.error("ValueRequired")
956
- }
957
-
958
- if (keyReq === "exclusive" || valueReq === "exclusive") {
959
- if (keyProvided && valueProvided) {
960
- throw ctx.error("KeyAndValueProvided")
961
- }
962
- if (!keyProvided && !valueProvided) {
963
- throw ctx.error("KeyOrValueRequired")
964
- }
965
- }
966
-
967
- const cleanups = new Map()
968
- if (valueProvided) {
969
- let cachedRx
970
- ctx.rx = (...args) => {
971
- if (!cachedRx) {
972
- cachedRx = genRx(value, {
973
- returnsValue: plugin.returnsValue,
974
- argNames: plugin.argNames,
975
- cleanups,
976
- })
977
- }
978
- return cachedRx(el, ...args)
979
- }
980
- }
981
-
982
- const cleanup = plugin.apply(ctx)
983
- if (cleanup) {
984
- cleanups.set("attribute", cleanup)
985
- }
986
-
987
- let elCleanups = removals.get(el)
988
- if (elCleanups) {
989
- const attrCleanups = elCleanups.get(rawKey)
990
- if (attrCleanups) {
991
- for (const oldCleanup of attrCleanups.values()) {
992
- oldCleanup()
993
- }
994
- }
995
- } else {
996
- elCleanups = new Map()
997
- removals.set(el, elCleanups)
998
- }
999
- elCleanups.set(rawKey, cleanups)
1000
- }
1001
- }
1002
-
1003
- const genRx = (
1004
- value,
1005
- { returnsValue = false, argNames = [], cleanups = new Map() } = {},
1006
- ) => {
1007
- if (/^\s*(?:async\s+)?(?:\(.*?\)\s*=>|[\w$]+\s*=>|function\s*[\w$]*\s*\()/.test(value)) {
1008
- const userFn = Function(`return (${value.trim()})`)()
1009
-
1010
- return (el, ...args) => {
1011
- const actionsProxy = new Proxy({}, {
1012
- get:
1013
- (_, name) =>
1014
- (...actionArgs) => {
1015
- const err = error.bind(0, {
1016
- plugin: { type: "action", name },
1017
- element: { id: el.id, tag: el.tagName },
1018
- expression: { fnContent: value, value },
1019
- })
1020
- const fn = actions[name]
1021
- if (fn) return fn({ el, evt: undefined, error: err, cleanups }, ...actionArgs)
1022
- throw err("UndefinedAction")
1023
- },
1024
- })
1025
-
1026
- const dataEvt = args[0] instanceof Event ? args[0] : new Event("datastar:expression")
1027
- Object.defineProperties(dataEvt, {
1028
- target: { value: el },
1029
- signals: { value: root },
1030
- actions: { value: actionsProxy },
1031
- window: { value: window },
1032
- })
1033
-
1034
- try {
1035
- return userFn(dataEvt)
1036
- } catch (e) {
1037
- console.error(e)
1038
- throw error(
1039
- {
1040
- element: { id: el.id, tag: el.tagName },
1041
- expression: { fnContent: value, value },
1042
- error: e.message,
1043
- },
1044
- "ExecuteExpression",
1045
- )
1046
- }
1047
- }
1048
- }
1049
-
1050
- let expr = ""
1051
- if (returnsValue) {
1052
- const statementRe =
1053
- /(\/(\\\/|[^/])*\/|"(\\"|[^"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;){]*)\s*\)\s*\(\s*\)|[^;])+/gm
1054
- const statements = value.trim().match(statementRe)
1055
- if (statements) {
1056
- const lastIdx = statements.length - 1
1057
- const last = statements[lastIdx].trim()
1058
- if (!last.startsWith("return")) {
1059
- statements[lastIdx] = `return (${last});`
1060
- }
1061
- expr = statements.join(";\n")
1062
- }
1063
- } else {
1064
- expr = value.trim()
1065
- }
1066
-
1067
- const escaped = new Map()
1068
- const escapeRe = RegExp(`(?:${DSP})(.*?)(?:${DSS})`, "gm")
1069
- let counter = 0
1070
- for (const match of expr.matchAll(escapeRe)) {
1071
- const k = match[1]
1072
- const v = `__escaped${counter++}`
1073
- escaped.set(v, k)
1074
- expr = expr.replace(DSP + k + DSS, v)
1075
- }
1076
-
1077
- expr = expr
1078
- .replace(/\$\['([a-zA-Z_$\d][\w$]*)'\]/g, "$$$1")
1079
- .replace(/\$([a-zA-Z_\d]\w*(?:[.-]\w+)*)/g, (_, signalName) =>
1080
- signalName.split(".").reduce((acc, part) => `${acc}['${part}']`, "$"),
1081
- )
1082
-
1083
- expr = expr.replaceAll(/@([A-Za-z_$][\w$]*)\(/g, '__action("$1",evt,')
1084
-
1085
- for (const [k, v] of escaped) {
1086
- expr = expr.replace(k, v)
1087
- }
1088
-
1089
- try {
1090
- const fn = Function("el", "$", "__action", "evt", ...argNames, expr)
1091
- return (el, ...args) => {
1092
- const action = (name, evt, ...args) => {
1093
- const err = error.bind(0, {
1094
- plugin: { type: "action", name },
1095
- element: { id: el.id, tag: el.tagName },
1096
- expression: {
1097
- fnContent: expr,
1098
- value,
1099
- },
1100
- })
1101
- const fn = actions[name]
1102
- if (fn) {
1103
- return fn(
1104
- {
1105
- el,
1106
- evt,
1107
- error: err,
1108
- cleanups,
1109
- },
1110
- ...args,
1111
- )
1112
- }
1113
- throw err("UndefinedAction")
1114
- }
1115
- try {
1116
- return fn(el, root, action, undefined, ...args)
1117
- } catch (e) {
1118
- console.error(e)
1119
- throw error(
1120
- {
1121
- element: { id: el.id, tag: el.tagName },
1122
- expression: {
1123
- fnContent: expr,
1124
- value,
1125
- },
1126
- error: e.message,
1127
- },
1128
- "ExecuteExpression",
1129
- )
1130
- }
1131
- }
1132
- } catch (e) {
1133
- console.error(e)
1134
- throw error(
1135
- {
1136
- expression: {
1137
- fnContent: expr,
1138
- value,
1139
- },
1140
- error: e.message,
1141
- },
1142
- "GenerateExpression",
1143
- )
1144
- }
1145
- }