effect-start 0.21.0 → 0.22.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/README.md +1 -4
- package/dist/Cookies.js +392 -0
- package/dist/FileSystem.js +131 -0
- package/dist/Socket.js +37 -0
- package/package.json +35 -36
- package/src/Commander.ts +73 -130
- package/src/ContentNegotiation.ts +64 -95
- package/src/Cookies.ts +36 -57
- package/src/Development.ts +47 -62
- package/src/Effectify.ts +222 -206
- package/src/Entity.ts +59 -86
- package/src/FilePathPattern.ts +5 -5
- package/src/FileRouter.ts +37 -62
- package/src/FileRouterCodegen.ts +63 -55
- package/src/FileSystem.ts +46 -59
- package/src/Http.ts +17 -50
- package/src/PathPattern.ts +33 -41
- package/src/PlatformError.ts +29 -50
- package/src/PlatformRuntime.ts +39 -47
- package/src/Route.ts +68 -187
- package/src/RouteBody.ts +45 -161
- package/src/RouteHook.ts +22 -45
- package/src/RouteHttp.ts +88 -142
- package/src/RouteHttpTracer.ts +25 -26
- package/src/RouteMount.ts +100 -238
- package/src/RouteSchema.ts +67 -201
- package/src/RouteSse.ts +28 -82
- package/src/RouteTree.ts +31 -79
- package/src/RouteTrie.ts +13 -32
- package/src/SchemaExtra.ts +3 -5
- package/src/Socket.ts +5 -2
- package/src/Start.ts +20 -21
- package/src/StreamExtra.ts +93 -96
- package/src/TuplePathPattern.ts +54 -43
- package/src/Unique.ts +9 -15
- package/src/Values.ts +26 -30
- package/src/bun/BunBundle.ts +27 -73
- package/src/bun/BunImportTrackerPlugin.ts +67 -65
- package/src/bun/BunRoute.ts +12 -31
- package/src/bun/BunRuntime.ts +3 -10
- package/src/bun/BunServer.ts +55 -91
- package/src/bun/BunVirtualFilesPlugin.ts +1 -4
- package/src/bun/_BunEnhancedResolve.ts +17 -42
- package/src/bun/_empty.html +0 -1
- package/src/bundler/Bundle.ts +20 -36
- package/src/bundler/BundleFiles.ts +35 -55
- package/src/client/Overlay.ts +1 -2
- package/src/client/ScrollState.ts +5 -9
- package/src/client/index.ts +10 -13
- package/src/datastar/actions/fetch.ts +29 -48
- package/src/datastar/actions/peek.ts +1 -5
- package/src/datastar/actions/setAll.ts +2 -2
- package/src/datastar/actions/toggleAll.ts +2 -2
- package/src/datastar/attributes/attr.ts +17 -18
- package/src/datastar/attributes/bind.ts +41 -61
- package/src/datastar/attributes/class.ts +2 -5
- package/src/datastar/attributes/computed.ts +2 -10
- package/src/datastar/attributes/effect.ts +1 -2
- package/src/datastar/attributes/indicator.ts +2 -8
- package/src/datastar/attributes/init.ts +2 -10
- package/src/datastar/attributes/jsonSignals.ts +1 -6
- package/src/datastar/attributes/on.ts +4 -13
- package/src/datastar/attributes/onIntersect.ts +10 -22
- package/src/datastar/attributes/onInterval.ts +2 -10
- package/src/datastar/attributes/onSignalPatch.ts +18 -28
- package/src/datastar/attributes/ref.ts +1 -2
- package/src/datastar/attributes/show.ts +1 -2
- package/src/datastar/attributes/signals.ts +1 -5
- package/src/datastar/attributes/style.ts +6 -12
- package/src/datastar/attributes/text.ts +1 -2
- package/src/datastar/engine.ts +102 -158
- package/src/datastar/index.ts +2 -2
- package/src/datastar/utils.ts +16 -51
- package/src/datastar/watchers/patchElements.ts +35 -93
- package/src/datastar/watchers/patchSignals.ts +1 -2
- package/src/experimental/EncryptedCookies.ts +79 -142
- package/src/hyper/Hyper.ts +14 -33
- package/src/hyper/HyperHtml.ts +9 -10
- package/src/hyper/HyperNode.ts +2 -7
- package/src/hyper/HyperRoute.ts +2 -5
- package/src/hyper/jsx-runtime.ts +2 -10
- package/src/hyper/jsx.d.ts +171 -440
- package/src/lint/plugin.js +276 -0
- package/src/node/NodeFileSystem.ts +138 -186
- package/src/node/NodeUtils.ts +1 -3
- package/src/testing/TestLogger.ts +9 -22
- package/src/testing/utils.ts +30 -31
- package/src/x/cloudflare/CloudflareTunnel.ts +37 -54
- package/src/x/datastar/Datastar.ts +3 -10
- package/src/x/datastar/index.ts +1 -3
- package/src/x/datastar/jsx-datastar.d.ts +1 -4
- package/src/x/tailwind/TailwindPlugin.ts +119 -112
- package/src/x/tailwind/compile.ts +10 -33
- package/src/x/tailwind/plugin.ts +2 -2
package/src/datastar/engine.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
aliasify,
|
|
3
|
-
hasOwn,
|
|
4
|
-
isHTMLOrSVG,
|
|
5
|
-
isPojo,
|
|
6
|
-
pathToObj,
|
|
7
|
-
snake,
|
|
8
|
-
} from "./utils.ts"
|
|
1
|
+
import { aliasify, hasOwn, isHTMLOrSVG, isPojo, pathToObj, snake } from "./utils.ts"
|
|
9
2
|
|
|
10
3
|
/*********
|
|
11
4
|
* consts.ts
|
|
@@ -20,7 +13,7 @@ export const DATASTAR_SIGNAL_PATCH_EVENT = "datastar-signal-patch"
|
|
|
20
13
|
* types.ts
|
|
21
14
|
*********/
|
|
22
15
|
export type JSONPatch = Record<string, any> & { length?: never }
|
|
23
|
-
export type Paths = [string, any]
|
|
16
|
+
export type Paths = Array<[string, any]>
|
|
24
17
|
|
|
25
18
|
export type DatastarFetchEvent = {
|
|
26
19
|
type: string
|
|
@@ -50,35 +43,31 @@ export type RequirementType = "allowed" | "must" | "denied" | "exclusive"
|
|
|
50
43
|
export type Requirement =
|
|
51
44
|
| RequirementType
|
|
52
45
|
| {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
key: Exclude<RequirementType, "exclusive">
|
|
47
|
+
value?: Exclude<RequirementType, "exclusive">
|
|
48
|
+
}
|
|
56
49
|
| {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
key?: Exclude<RequirementType, "exclusive">
|
|
51
|
+
value: Exclude<RequirementType, "exclusive">
|
|
52
|
+
}
|
|
60
53
|
|
|
61
|
-
type Rx<B extends boolean> = (...args: any
|
|
54
|
+
type Rx<B extends boolean> = (...args: Array<any>) => B extends true ? unknown : void
|
|
62
55
|
|
|
63
|
-
type ReqField<R, K extends "key" | "value", Return> = R extends
|
|
64
|
-
|
|
65
|
-
| { [P in K]: "
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
| (K extends keyof R ? never : R) ? Return | undefined
|
|
71
|
-
: never
|
|
56
|
+
type ReqField<R, K extends "key" | "value", Return> = R extends "must" | { [P in K]: "must" }
|
|
57
|
+
? Return
|
|
58
|
+
: R extends "denied" | { [P in K]: "denied" }
|
|
59
|
+
? undefined
|
|
60
|
+
: R extends "allowed" | { [P in K]: "allowed" } | (K extends keyof R ? never : R)
|
|
61
|
+
? Return | undefined
|
|
62
|
+
: never
|
|
72
63
|
|
|
73
64
|
type ReqFields<R extends Requirement, B extends boolean> = R extends "exclusive"
|
|
74
|
-
?
|
|
75
|
-
| { key: string; value: undefined; rx: undefined }
|
|
76
|
-
| { key: undefined; value: string; rx: Rx<B> }
|
|
65
|
+
? { key: string; value: undefined; rx: undefined } | { key: undefined; value: string; rx: Rx<B> }
|
|
77
66
|
: {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
key: ReqField<R, "key", string>
|
|
68
|
+
value: ReqField<R, "value", string>
|
|
69
|
+
rx: ReqField<R, "value", Rx<B>>
|
|
70
|
+
}
|
|
82
71
|
|
|
83
72
|
export type AttributeContext<
|
|
84
73
|
R extends Requirement = Requirement,
|
|
@@ -103,7 +92,7 @@ export type AttributePlugin<
|
|
|
103
92
|
apply: (ctx: AttributeContext<R, RxReturn>) => void | (() => void)
|
|
104
93
|
requirement?: R
|
|
105
94
|
returnsValue?: RxReturn
|
|
106
|
-
argNames?: string
|
|
95
|
+
argNames?: Array<string>
|
|
107
96
|
}
|
|
108
97
|
|
|
109
98
|
export type WatcherContext = {
|
|
@@ -119,7 +108,7 @@ export type ActionPlugins = Record<string, ActionPlugin>
|
|
|
119
108
|
|
|
120
109
|
export type ActionPlugin<T = any> = {
|
|
121
110
|
name: string
|
|
122
|
-
apply: (ctx: ActionContext, ...args: any
|
|
111
|
+
apply: (ctx: ActionContext, ...args: Array<any>) => T
|
|
123
112
|
}
|
|
124
113
|
|
|
125
114
|
export type MergePatchArgs = {
|
|
@@ -129,7 +118,7 @@ export type MergePatchArgs = {
|
|
|
129
118
|
export type HTMLOrSVG = HTMLElement | SVGElement | MathMLElement
|
|
130
119
|
export type Modifiers = Map<string, Set<string>>
|
|
131
120
|
|
|
132
|
-
export type EventCallbackHandler = (...args: any
|
|
121
|
+
export type EventCallbackHandler = (...args: Array<any>) => void
|
|
133
122
|
|
|
134
123
|
export type SignalFilter = RegExp
|
|
135
124
|
export type SignalFilterOptions = {
|
|
@@ -181,7 +170,7 @@ const ReactiveFlags = {
|
|
|
181
170
|
Dirty: 1 << 4,
|
|
182
171
|
Pending: 1 << 5,
|
|
183
172
|
} as const
|
|
184
|
-
type ReactiveFlags = typeof ReactiveFlags[keyof typeof ReactiveFlags]
|
|
173
|
+
type ReactiveFlags = (typeof ReactiveFlags)[keyof typeof ReactiveFlags]
|
|
185
174
|
type ReactiveFlags_None = typeof ReactiveFlags.None
|
|
186
175
|
type ReactiveFlags_Mutable = typeof ReactiveFlags.Mutable
|
|
187
176
|
type ReactiveFlags_Watching = typeof ReactiveFlags.Watching
|
|
@@ -210,7 +199,7 @@ interface AlienSignal<T = unknown> extends ReactiveNode {
|
|
|
210
199
|
}
|
|
211
200
|
|
|
212
201
|
const currentPatch: Paths = []
|
|
213
|
-
const queuedEffects:
|
|
202
|
+
const queuedEffects: Array<AlienEffect | undefined> = []
|
|
214
203
|
let batchDepth = 0
|
|
215
204
|
let notifyIndex = 0
|
|
216
205
|
let queuedEffectsLength = 0
|
|
@@ -281,7 +270,7 @@ const flush = () => {
|
|
|
281
270
|
while (notifyIndex < queuedEffectsLength) {
|
|
282
271
|
const effect = queuedEffects[notifyIndex]!
|
|
283
272
|
queuedEffects[notifyIndex++] = undefined
|
|
284
|
-
run(effect, effect.flags_ &= ~EffectFlags.Queued)
|
|
273
|
+
run(effect, (effect.flags_ &= ~EffectFlags.Queued))
|
|
285
274
|
}
|
|
286
275
|
notifyIndex = 0
|
|
287
276
|
queuedEffectsLength = 0
|
|
@@ -326,8 +315,8 @@ const notify = (e: AlienEffect): void => {
|
|
|
326
315
|
|
|
327
316
|
const run = (e: AlienEffect, flags: ReactiveFlags): void => {
|
|
328
317
|
if (
|
|
329
|
-
flags & (16 satisfies ReactiveFlags_Dirty)
|
|
330
|
-
|
|
318
|
+
flags & (16 satisfies ReactiveFlags_Dirty) ||
|
|
319
|
+
(flags & (32 satisfies ReactiveFlags_Pending) && checkDirty(e.deps_!, e))
|
|
331
320
|
) {
|
|
332
321
|
startPeeking(e)
|
|
333
322
|
startTracking(e)
|
|
@@ -349,7 +338,7 @@ const run = (e: AlienEffect, flags: ReactiveFlags): void => {
|
|
|
349
338
|
const dep = link.dep_
|
|
350
339
|
const depFlags = dep.flags_
|
|
351
340
|
if (depFlags & EffectFlags.Queued) {
|
|
352
|
-
run(dep as AlienEffect, dep.flags_ = depFlags & ~EffectFlags.Queued)
|
|
341
|
+
run(dep as AlienEffect, (dep.flags_ = depFlags & ~EffectFlags.Queued))
|
|
353
342
|
}
|
|
354
343
|
link = link.nextDep_
|
|
355
344
|
}
|
|
@@ -388,8 +377,8 @@ const signalOper = <T>(s: AlienSignal<T>, ...value: [T]): T | boolean => {
|
|
|
388
377
|
const computedOper = <T>(c: AlienComputed<T>): T => {
|
|
389
378
|
const flags = c.flags_
|
|
390
379
|
if (
|
|
391
|
-
flags & (16 satisfies ReactiveFlags_Dirty)
|
|
392
|
-
|
|
380
|
+
flags & (16 satisfies ReactiveFlags_Dirty) ||
|
|
381
|
+
(flags & (32 satisfies ReactiveFlags_Pending) && checkDirty(c.deps_!, c))
|
|
393
382
|
) {
|
|
394
383
|
if (updateComputed(c)) {
|
|
395
384
|
const subs = c.subs_
|
|
@@ -433,7 +422,8 @@ const link = (dep: ReactiveNode, sub: ReactiveNode): void => {
|
|
|
433
422
|
if (prevSub && prevSub.version_ === version && prevSub.sub_ === sub) {
|
|
434
423
|
return
|
|
435
424
|
}
|
|
436
|
-
const newLink =
|
|
425
|
+
const newLink =
|
|
426
|
+
(sub.depsTail_ =
|
|
437
427
|
dep.subsTail_ =
|
|
438
428
|
{
|
|
439
429
|
version_: version,
|
|
@@ -508,8 +498,8 @@ const propagate = (link: Link): void => {
|
|
|
508
498
|
|
|
509
499
|
if (
|
|
510
500
|
!(
|
|
511
|
-
flags
|
|
512
|
-
|
|
501
|
+
flags &
|
|
502
|
+
(60 as
|
|
513
503
|
| ReactiveFlags_RecursedCheck
|
|
514
504
|
| ReactiveFlags_Recursed
|
|
515
505
|
| ReactiveFlags_Dirty
|
|
@@ -517,19 +507,16 @@ const propagate = (link: Link): void => {
|
|
|
517
507
|
)
|
|
518
508
|
) {
|
|
519
509
|
sub.flags_ = flags | (32 satisfies ReactiveFlags_Pending)
|
|
520
|
-
} else if (
|
|
521
|
-
!(flags & (12 as ReactiveFlags_RecursedCheck | ReactiveFlags_Recursed))
|
|
522
|
-
) {
|
|
510
|
+
} else if (!(flags & (12 as ReactiveFlags_RecursedCheck | ReactiveFlags_Recursed))) {
|
|
523
511
|
flags = 0 satisfies ReactiveFlags_None
|
|
524
512
|
} else if (!(flags & (4 satisfies ReactiveFlags_RecursedCheck))) {
|
|
525
|
-
sub.flags_ =
|
|
526
|
-
| (32 satisfies ReactiveFlags_Pending)
|
|
513
|
+
sub.flags_ =
|
|
514
|
+
(flags & ~(8 satisfies ReactiveFlags_Recursed)) | (32 satisfies ReactiveFlags_Pending)
|
|
527
515
|
} else if (
|
|
528
|
-
!(flags & (48 as ReactiveFlags_Dirty | ReactiveFlags_Pending))
|
|
529
|
-
|
|
516
|
+
!(flags & (48 as ReactiveFlags_Dirty | ReactiveFlags_Pending)) &&
|
|
517
|
+
isValidLink(link, sub)
|
|
530
518
|
) {
|
|
531
|
-
sub.flags_ = flags
|
|
532
|
-
| (40 as ReactiveFlags_Recursed | ReactiveFlags_Pending)
|
|
519
|
+
sub.flags_ = flags | (40 as ReactiveFlags_Recursed | ReactiveFlags_Pending)
|
|
533
520
|
flags &= 1 satisfies ReactiveFlags_Mutable
|
|
534
521
|
} else {
|
|
535
522
|
flags = 0 satisfies ReactiveFlags_None
|
|
@@ -572,12 +559,9 @@ const propagate = (link: Link): void => {
|
|
|
572
559
|
const startTracking = (sub: ReactiveNode): void => {
|
|
573
560
|
version++
|
|
574
561
|
sub.depsTail_ = undefined
|
|
575
|
-
sub.flags_ =
|
|
576
|
-
& ~(56 as
|
|
577
|
-
|
|
578
|
-
| ReactiveFlags_Dirty
|
|
579
|
-
| ReactiveFlags_Pending))
|
|
580
|
-
| (4 satisfies ReactiveFlags_RecursedCheck)
|
|
562
|
+
sub.flags_ =
|
|
563
|
+
(sub.flags_ & ~(56 as ReactiveFlags_Recursed | ReactiveFlags_Dirty | ReactiveFlags_Pending)) |
|
|
564
|
+
(4 satisfies ReactiveFlags_RecursedCheck)
|
|
581
565
|
}
|
|
582
566
|
|
|
583
567
|
const endTracking = (sub: ReactiveNode): void => {
|
|
@@ -601,8 +585,8 @@ const checkDirty = (link: Link, sub: ReactiveNode): boolean => {
|
|
|
601
585
|
if (sub.flags_ & (16 satisfies ReactiveFlags_Dirty)) {
|
|
602
586
|
dirty = true
|
|
603
587
|
} else if (
|
|
604
|
-
(flags & (17 as ReactiveFlags_Mutable | ReactiveFlags_Dirty))
|
|
605
|
-
|
|
588
|
+
(flags & (17 as ReactiveFlags_Mutable | ReactiveFlags_Dirty)) ===
|
|
589
|
+
(17 as ReactiveFlags_Mutable | ReactiveFlags_Dirty)
|
|
606
590
|
) {
|
|
607
591
|
if (update(dep as AlienSignal | AlienComputed)) {
|
|
608
592
|
const subs = dep.subs_!
|
|
@@ -612,8 +596,8 @@ const checkDirty = (link: Link, sub: ReactiveNode): boolean => {
|
|
|
612
596
|
dirty = true
|
|
613
597
|
}
|
|
614
598
|
} else if (
|
|
615
|
-
(flags & (33 as ReactiveFlags_Mutable | ReactiveFlags_Pending))
|
|
616
|
-
|
|
599
|
+
(flags & (33 as ReactiveFlags_Mutable | ReactiveFlags_Pending)) ===
|
|
600
|
+
(33 as ReactiveFlags_Mutable | ReactiveFlags_Pending)
|
|
617
601
|
) {
|
|
618
602
|
if (link.nextSub_ || link.prevSub_) {
|
|
619
603
|
stack = { value_: link, prev_: stack }
|
|
@@ -669,8 +653,8 @@ const shallowPropagate = (link: Link): void => {
|
|
|
669
653
|
const sub = link.sub_
|
|
670
654
|
const flags = sub.flags_
|
|
671
655
|
if (
|
|
672
|
-
(flags & (48 as ReactiveFlags_Pending | ReactiveFlags_Dirty))
|
|
673
|
-
|
|
656
|
+
(flags & (48 as ReactiveFlags_Pending | ReactiveFlags_Dirty)) ===
|
|
657
|
+
(32 satisfies ReactiveFlags_Pending)
|
|
674
658
|
) {
|
|
675
659
|
sub.flags_ = flags | (16 satisfies ReactiveFlags_Dirty)
|
|
676
660
|
if (flags & (2 satisfies ReactiveFlags_Watching)) {
|
|
@@ -708,9 +692,7 @@ const deep = (value: any, prefix = ""): any => {
|
|
|
708
692
|
if (isArr || isPojo(value)) {
|
|
709
693
|
const deepObj = (isArr ? [] : {}) as Record<string, Signal<any>>
|
|
710
694
|
for (const key in value) {
|
|
711
|
-
deepObj[key] = signal(
|
|
712
|
-
deep((value as Record<string, Signal<any>>)[key], `${prefix + key}.`),
|
|
713
|
-
)
|
|
695
|
+
deepObj[key] = signal(deep((value as Record<string, Signal<any>>)[key], `${prefix + key}.`))
|
|
714
696
|
}
|
|
715
697
|
const keys = signal(0)
|
|
716
698
|
return new Proxy(deepObj, {
|
|
@@ -816,10 +798,7 @@ const dispatch = (path?: string, value?: any) => {
|
|
|
816
798
|
}
|
|
817
799
|
}
|
|
818
800
|
|
|
819
|
-
export const mergePatch = (
|
|
820
|
-
patch: JSONPatch,
|
|
821
|
-
{ ifMissing }: MergePatchArgs = {},
|
|
822
|
-
): void => {
|
|
801
|
+
export const mergePatch = (patch: JSONPatch, { ifMissing }: MergePatchArgs = {}): void => {
|
|
823
802
|
beginBatch()
|
|
824
803
|
for (const key in patch) {
|
|
825
804
|
if (patch[key] == null) {
|
|
@@ -846,8 +825,8 @@ const mergeInner = (
|
|
|
846
825
|
if (isPojo(patch)) {
|
|
847
826
|
if (
|
|
848
827
|
!(
|
|
849
|
-
hasOwn(targetParent, target)
|
|
850
|
-
|
|
828
|
+
hasOwn(targetParent, target) &&
|
|
829
|
+
(isPojo(targetParent[target]) || Array.isArray(targetParent[target]))
|
|
851
830
|
)
|
|
852
831
|
) {
|
|
853
832
|
targetParent[target] = {}
|
|
@@ -859,13 +838,7 @@ const mergeInner = (
|
|
|
859
838
|
delete targetParent[target][key]
|
|
860
839
|
}
|
|
861
840
|
} else {
|
|
862
|
-
mergeInner(
|
|
863
|
-
patch[key],
|
|
864
|
-
key,
|
|
865
|
-
targetParent[target],
|
|
866
|
-
`${prefix + target}.`,
|
|
867
|
-
ifMissing,
|
|
868
|
-
)
|
|
841
|
+
mergeInner(patch[key], key, targetParent[target], `${prefix + target}.`, ifMissing)
|
|
869
842
|
}
|
|
870
843
|
}
|
|
871
844
|
} else if (!(ifMissing && hasOwn(targetParent, target))) {
|
|
@@ -883,7 +856,7 @@ export const filtered = (
|
|
|
883
856
|
const includeRe = toRegExp(include)
|
|
884
857
|
const excludeRe = toRegExp(exclude)
|
|
885
858
|
const paths: Paths = []
|
|
886
|
-
const stack: [any, string]
|
|
859
|
+
const stack: Array<[any, string]> = [[obj, ""]]
|
|
887
860
|
|
|
888
861
|
while (stack.length) {
|
|
889
862
|
const [node, prefix] = stack.pop()!
|
|
@@ -908,18 +881,13 @@ export const root: Record<string, any> = deep({})
|
|
|
908
881
|
*********/
|
|
909
882
|
const url = "https://data-star.dev/errors"
|
|
910
883
|
|
|
911
|
-
const error = (
|
|
912
|
-
ctx: Record<string, any>,
|
|
913
|
-
reason: string,
|
|
914
|
-
metadata: Record<string, any> = {},
|
|
915
|
-
) => {
|
|
884
|
+
const error = (ctx: Record<string, any>, reason: string, metadata: Record<string, any> = {}) => {
|
|
916
885
|
Object.assign(metadata, ctx)
|
|
917
886
|
const e = new Error()
|
|
918
887
|
const r = snake(reason)
|
|
919
888
|
const q = new URLSearchParams({
|
|
920
889
|
metadata: JSON.stringify(metadata),
|
|
921
|
-
})
|
|
922
|
-
.toString()
|
|
890
|
+
}).toString()
|
|
923
891
|
const c = JSON.stringify(metadata, null, 2)
|
|
924
892
|
e.message = `${reason}\nMore info: ${url}/${r}?${q}\nContext: ${c}`
|
|
925
893
|
return e
|
|
@@ -929,10 +897,7 @@ const actionPlugins: Map<string, ActionPlugin> = new Map()
|
|
|
929
897
|
const attributePlugins: Map<string, AttributePlugin> = new Map()
|
|
930
898
|
const watcherPlugins: Map<string, WatcherPlugin> = new Map()
|
|
931
899
|
|
|
932
|
-
export const actions: Record<
|
|
933
|
-
string,
|
|
934
|
-
(ctx: ActionContext, ...args: any[]) => any
|
|
935
|
-
> = new Proxy(
|
|
900
|
+
export const actions: Record<string, (ctx: ActionContext, ...args: Array<any>) => any> = new Proxy(
|
|
936
901
|
{},
|
|
937
902
|
{
|
|
938
903
|
get: (_, prop: string) => actionPlugins.get(prop)?.apply,
|
|
@@ -945,7 +910,7 @@ export const actions: Record<
|
|
|
945
910
|
|
|
946
911
|
const removals = new Map<HTMLOrSVG, Map<string, Map<string, () => void>>>()
|
|
947
912
|
|
|
948
|
-
const queuedAttributes: AttributePlugin
|
|
913
|
+
const queuedAttributes: Array<AttributePlugin> = []
|
|
949
914
|
const queuedAttributeNames = new Set<string>()
|
|
950
915
|
const observedRoots = new WeakSet<Node>()
|
|
951
916
|
export const attribute = <R extends Requirement, B extends boolean>(
|
|
@@ -970,28 +935,23 @@ export const action = <T>(plugin: ActionPlugin<T>): void => {
|
|
|
970
935
|
actionPlugins.set(plugin.name, plugin)
|
|
971
936
|
}
|
|
972
937
|
|
|
973
|
-
document.addEventListener(
|
|
974
|
-
|
|
975
|
-
(
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
evt.detail.argsRaw,
|
|
991
|
-
)
|
|
992
|
-
}
|
|
993
|
-
}) as EventListener,
|
|
994
|
-
)
|
|
938
|
+
document.addEventListener(DATASTAR_FETCH_EVENT, ((evt: CustomEvent<DatastarFetchEvent>) => {
|
|
939
|
+
const plugin = watcherPlugins.get(evt.detail.type)
|
|
940
|
+
if (plugin) {
|
|
941
|
+
plugin.apply(
|
|
942
|
+
{
|
|
943
|
+
error: error.bind(0, {
|
|
944
|
+
plugin: { type: "watcher", name: plugin.name },
|
|
945
|
+
element: {
|
|
946
|
+
id: (evt.target as Element).id,
|
|
947
|
+
tag: (evt.target as Element).tagName,
|
|
948
|
+
},
|
|
949
|
+
}),
|
|
950
|
+
},
|
|
951
|
+
evt.detail.argsRaw,
|
|
952
|
+
)
|
|
953
|
+
}
|
|
954
|
+
}) as EventListener)
|
|
995
955
|
|
|
996
956
|
export const watcher = (plugin: WatcherPlugin): void => {
|
|
997
957
|
watcherPlugins.set(plugin.name, plugin)
|
|
@@ -1030,16 +990,8 @@ const applyEls = (els: Iterable<HTMLOrSVG>, onlyNew?: boolean): void => {
|
|
|
1030
990
|
}
|
|
1031
991
|
}
|
|
1032
992
|
|
|
1033
|
-
const observe = (mutations: MutationRecord
|
|
1034
|
-
for (
|
|
1035
|
-
const {
|
|
1036
|
-
target,
|
|
1037
|
-
type,
|
|
1038
|
-
attributeName,
|
|
1039
|
-
addedNodes,
|
|
1040
|
-
removedNodes,
|
|
1041
|
-
} of mutations
|
|
1042
|
-
) {
|
|
993
|
+
const observe = (mutations: Array<MutationRecord>) => {
|
|
994
|
+
for (const { target, type, attributeName, addedNodes, removedNodes } of mutations) {
|
|
1043
995
|
if (type === "childList") {
|
|
1044
996
|
for (const node of removedNodes) {
|
|
1045
997
|
if (isHTMLOrSVG(node)) {
|
|
@@ -1055,10 +1007,10 @@ const observe = (mutations: MutationRecord[]) => {
|
|
|
1055
1007
|
}
|
|
1056
1008
|
}
|
|
1057
1009
|
} else if (
|
|
1058
|
-
type === "attributes"
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1010
|
+
type === "attributes" &&
|
|
1011
|
+
attributeName!.startsWith("data-") &&
|
|
1012
|
+
isHTMLOrSVG(target) &&
|
|
1013
|
+
!shouldIgnore(target)
|
|
1062
1014
|
) {
|
|
1063
1015
|
const key = attributeName!.slice(5)
|
|
1064
1016
|
const value = target.getAttribute(attributeName!)
|
|
@@ -1101,8 +1053,7 @@ export const parseAttributeKey = (
|
|
|
1101
1053
|
return { pluginName, key, mods }
|
|
1102
1054
|
}
|
|
1103
1055
|
|
|
1104
|
-
export const isDocumentObserverActive = () =>
|
|
1105
|
-
observedRoots.has(document.documentElement)
|
|
1056
|
+
export const isDocumentObserverActive = () => observedRoots.has(document.documentElement)
|
|
1106
1057
|
|
|
1107
1058
|
export const apply = (
|
|
1108
1059
|
root: HTMLOrSVG | ShadowRoot = document.documentElement,
|
|
@@ -1151,16 +1102,14 @@ const applyAttributePlugin = (
|
|
|
1151
1102
|
rx: undefined,
|
|
1152
1103
|
} as AttributeContext
|
|
1153
1104
|
|
|
1154
|
-
const keyReq =
|
|
1155
|
-
|
|
1156
|
-
? plugin.requirement
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
: plugin.requirement.value))
|
|
1163
|
-
|| "allowed"
|
|
1105
|
+
const keyReq =
|
|
1106
|
+
(plugin.requirement &&
|
|
1107
|
+
(typeof plugin.requirement === "string" ? plugin.requirement : plugin.requirement.key)) ||
|
|
1108
|
+
"allowed"
|
|
1109
|
+
const valueReq =
|
|
1110
|
+
(plugin.requirement &&
|
|
1111
|
+
(typeof plugin.requirement === "string" ? plugin.requirement : plugin.requirement.value)) ||
|
|
1112
|
+
"allowed"
|
|
1164
1113
|
|
|
1165
1114
|
const keyProvided = key !== undefined && key !== null && key !== ""
|
|
1166
1115
|
const valueProvided = value !== undefined && value !== null && value !== ""
|
|
@@ -1193,7 +1142,7 @@ const applyAttributePlugin = (
|
|
|
1193
1142
|
const cleanups = new Map<string, () => void>()
|
|
1194
1143
|
if (valueProvided) {
|
|
1195
1144
|
let cachedRx: GenRxFn
|
|
1196
|
-
ctx.rx = (...args: any
|
|
1145
|
+
ctx.rx = (...args: Array<any>) => {
|
|
1197
1146
|
if (!cachedRx) {
|
|
1198
1147
|
cachedRx = genRx(value, {
|
|
1199
1148
|
returnsValue: plugin.returnsValue,
|
|
@@ -1228,19 +1177,15 @@ const applyAttributePlugin = (
|
|
|
1228
1177
|
|
|
1229
1178
|
type GenRxOptions = {
|
|
1230
1179
|
returnsValue?: boolean
|
|
1231
|
-
argNames?: string
|
|
1180
|
+
argNames?: Array<string>
|
|
1232
1181
|
cleanups?: Map<string, () => void>
|
|
1233
1182
|
}
|
|
1234
1183
|
|
|
1235
|
-
type GenRxFn = <T>(el: HTMLOrSVG, ...args: any
|
|
1184
|
+
type GenRxFn = <T>(el: HTMLOrSVG, ...args: Array<any>) => T
|
|
1236
1185
|
|
|
1237
1186
|
const genRx = (
|
|
1238
1187
|
value: string,
|
|
1239
|
-
{
|
|
1240
|
-
returnsValue = false,
|
|
1241
|
-
argNames = [],
|
|
1242
|
-
cleanups = new Map(),
|
|
1243
|
-
}: GenRxOptions = {},
|
|
1188
|
+
{ returnsValue = false, argNames = [], cleanups = new Map() }: GenRxOptions = {},
|
|
1244
1189
|
): GenRxFn => {
|
|
1245
1190
|
let expr = ""
|
|
1246
1191
|
if (returnsValue) {
|
|
@@ -1272,11 +1217,10 @@ const genRx = (
|
|
|
1272
1217
|
expr = expr
|
|
1273
1218
|
.replace(/\$\['([a-zA-Z_$\d][\w$]*)'\]/g, "$$$1")
|
|
1274
1219
|
.replace(/\$([a-zA-Z_\d]\w*(?:[.-]\w+)*)/g, (_, signalName) =>
|
|
1275
|
-
signalName
|
|
1276
|
-
|
|
1277
|
-
.reduce((acc: string, part: string) => `${acc}['${part}']`, "$"))
|
|
1220
|
+
signalName.split(".").reduce((acc: string, part: string) => `${acc}['${part}']`, "$"),
|
|
1221
|
+
)
|
|
1278
1222
|
|
|
1279
|
-
expr = expr.replaceAll(/@([A-Za-z_$][\w$]*)\(/g,
|
|
1223
|
+
expr = expr.replaceAll(/@([A-Za-z_$][\w$]*)\(/g, '__action("$1",evt,')
|
|
1280
1224
|
|
|
1281
1225
|
for (const [k, v] of escaped) {
|
|
1282
1226
|
expr = expr.replace(k, v)
|
|
@@ -1284,8 +1228,8 @@ const genRx = (
|
|
|
1284
1228
|
|
|
1285
1229
|
try {
|
|
1286
1230
|
const fn = Function("el", "$", "__action", "evt", ...argNames, expr)
|
|
1287
|
-
return (el: HTMLOrSVG, ...args: any
|
|
1288
|
-
const action = (name: string, evt: Event | undefined, ...args: any
|
|
1231
|
+
return (el: HTMLOrSVG, ...args: Array<any>) => {
|
|
1232
|
+
const action = (name: string, evt: Event | undefined, ...args: Array<any>) => {
|
|
1289
1233
|
const err = error.bind(0, {
|
|
1290
1234
|
plugin: { type: "action", name },
|
|
1291
1235
|
element: { id: el.id, tag: el.tagName },
|
package/src/datastar/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export * from "./engine.ts"
|
|
2
|
-
|
|
3
1
|
import "./actions/peek.ts"
|
|
4
2
|
import "./actions/setAll.ts"
|
|
5
3
|
import "./actions/toggleAll.ts"
|
|
@@ -23,3 +21,5 @@ import "./attributes/style.ts"
|
|
|
23
21
|
import "./attributes/text.ts"
|
|
24
22
|
import "./watchers/patchElements.ts"
|
|
25
23
|
import "./watchers/patchSignals.ts"
|
|
24
|
+
|
|
25
|
+
export * from "./engine.ts"
|
package/src/datastar/utils.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
EventCallbackHandler,
|
|
3
|
-
HTMLOrSVG,
|
|
4
|
-
Modifiers,
|
|
5
|
-
Paths,
|
|
6
|
-
} from "./engine.ts"
|
|
1
|
+
import type { EventCallbackHandler, HTMLOrSVG, Modifiers, Paths } from "./engine.ts"
|
|
7
2
|
|
|
8
3
|
/*********
|
|
9
4
|
* dom.ts
|
|
10
5
|
*********/
|
|
11
6
|
export const isHTMLOrSVG = (el: Node): el is HTMLOrSVG =>
|
|
12
|
-
el instanceof HTMLElement
|
|
13
|
-
|| el instanceof SVGElement
|
|
14
|
-
|| el instanceof MathMLElement
|
|
7
|
+
el instanceof HTMLElement || el instanceof SVGElement || el instanceof MathMLElement
|
|
15
8
|
|
|
16
9
|
/*********
|
|
17
10
|
* math.ts
|
|
@@ -20,22 +13,12 @@ export const clamp = (value: number, min: number, max: number): number => {
|
|
|
20
13
|
return Math.max(min, Math.min(max, value))
|
|
21
14
|
}
|
|
22
15
|
|
|
23
|
-
export const lerp = (
|
|
24
|
-
min: number,
|
|
25
|
-
max: number,
|
|
26
|
-
t: number,
|
|
27
|
-
clamped = true,
|
|
28
|
-
): number => {
|
|
16
|
+
export const lerp = (min: number, max: number, t: number, clamped = true): number => {
|
|
29
17
|
const v = min + (max - min) * t
|
|
30
18
|
return clamped ? clamp(v, min, max) : v
|
|
31
19
|
}
|
|
32
20
|
|
|
33
|
-
export const inverseLerp = (
|
|
34
|
-
min: number,
|
|
35
|
-
max: number,
|
|
36
|
-
value: number,
|
|
37
|
-
clamped = true,
|
|
38
|
-
): number => {
|
|
21
|
+
export const inverseLerp = (min: number, max: number, value: number, clamped = true): number => {
|
|
39
22
|
if (value < min) return 0
|
|
40
23
|
if (value > max) return 1
|
|
41
24
|
const v = (value - min) / (max - min)
|
|
@@ -67,16 +50,14 @@ export const kebab = (str: string): string =>
|
|
|
67
50
|
.replace(/[\s_]+/g, "-")
|
|
68
51
|
.toLowerCase()
|
|
69
52
|
|
|
70
|
-
export const camel = (str: string): string =>
|
|
71
|
-
kebab(str).replace(/-./g, (x) => x[1].toUpperCase())
|
|
53
|
+
export const camel = (str: string): string => kebab(str).replace(/-./g, (x) => x[1].toUpperCase())
|
|
72
54
|
|
|
73
55
|
export const snake = (str: string): string => kebab(str).replace(/-/g, "_")
|
|
74
56
|
|
|
75
57
|
export const pascal = (str: string): string =>
|
|
76
58
|
camel(str).replace(/(^.|(?<=\.).)/g, (x) => x[0].toUpperCase())
|
|
77
59
|
|
|
78
|
-
export const title = (str: string): string =>
|
|
79
|
-
str.replace(/\b\w/g, (char) => char.toUpperCase())
|
|
60
|
+
export const title = (str: string): string => str.replace(/\b\w/g, (char) => char.toUpperCase())
|
|
80
61
|
|
|
81
62
|
export const jsStrToObject = (raw: string) => {
|
|
82
63
|
try {
|
|
@@ -92,11 +73,7 @@ const caseFns: Record<string, (s: string) => string> = {
|
|
|
92
73
|
pascal: (str) => str[0].toUpperCase() + caseFns.camel(str.slice(1)),
|
|
93
74
|
}
|
|
94
75
|
|
|
95
|
-
export const modifyCasing = (
|
|
96
|
-
str: string,
|
|
97
|
-
mods: Modifiers,
|
|
98
|
-
defaultCase = "camel",
|
|
99
|
-
): string => {
|
|
76
|
+
export const modifyCasing = (str: string, mods: Modifiers, defaultCase = "camel"): string => {
|
|
100
77
|
for (const c of mods.get("case") || [defaultCase]) {
|
|
101
78
|
str = caseFns[c]?.(str) || str
|
|
102
79
|
}
|
|
@@ -124,11 +101,7 @@ export const tagToMs = (args: Set<string>) => {
|
|
|
124
101
|
return 0
|
|
125
102
|
}
|
|
126
103
|
|
|
127
|
-
export const tagHas = (
|
|
128
|
-
tags: Set<string>,
|
|
129
|
-
tag: string,
|
|
130
|
-
defaultValue = false,
|
|
131
|
-
) => {
|
|
104
|
+
export const tagHas = (tags: Set<string>, tag: string, defaultValue = false) => {
|
|
132
105
|
if (!tags) return defaultValue
|
|
133
106
|
return tags.has(tag.toLowerCase())
|
|
134
107
|
}
|
|
@@ -153,10 +126,9 @@ export const hasOwn: (obj: object, prop: PropertyKey) => boolean =
|
|
|
153
126
|
* paths.ts
|
|
154
127
|
*********/
|
|
155
128
|
export const isPojo = (obj: any): obj is Record<string, any> =>
|
|
156
|
-
obj !== null
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|| Object.getPrototypeOf(obj) === null)
|
|
129
|
+
obj !== null &&
|
|
130
|
+
typeof obj === "object" &&
|
|
131
|
+
(Object.getPrototypeOf(obj) === Object.prototype || Object.getPrototypeOf(obj) === null)
|
|
160
132
|
|
|
161
133
|
export const isEmpty = (obj: Record<string, any>): boolean => {
|
|
162
134
|
for (const prop in obj) {
|
|
@@ -167,10 +139,7 @@ export const isEmpty = (obj: Record<string, any>): boolean => {
|
|
|
167
139
|
return true
|
|
168
140
|
}
|
|
169
141
|
|
|
170
|
-
export const updateLeaves = (
|
|
171
|
-
obj: Record<string, any>,
|
|
172
|
-
fn: (oldValue: any) => any,
|
|
173
|
-
) => {
|
|
142
|
+
export const updateLeaves = (obj: Record<string, any>, fn: (oldValue: any) => any) => {
|
|
174
143
|
for (const key in obj) {
|
|
175
144
|
const val = obj[key]
|
|
176
145
|
if (isPojo(val) || Array.isArray(val)) {
|
|
@@ -195,11 +164,8 @@ export const pathToObj = (paths: Paths): Record<string, any> => {
|
|
|
195
164
|
/*********
|
|
196
165
|
* timing.ts
|
|
197
166
|
*********/
|
|
198
|
-
export const delay = (
|
|
199
|
-
|
|
200
|
-
wait: number,
|
|
201
|
-
): EventCallbackHandler => {
|
|
202
|
-
return (...args: any[]) => {
|
|
167
|
+
export const delay = (callback: EventCallbackHandler, wait: number): EventCallbackHandler => {
|
|
168
|
+
return (...args: Array<any>) => {
|
|
203
169
|
setTimeout(() => {
|
|
204
170
|
callback(...args)
|
|
205
171
|
}, wait)
|
|
@@ -216,7 +182,7 @@ export const throttle = (
|
|
|
216
182
|
let lastArgs: Parameters<EventCallbackHandler> | null = null
|
|
217
183
|
let timer: any = 0
|
|
218
184
|
|
|
219
|
-
return (...args: any
|
|
185
|
+
return (...args: Array<any>) => {
|
|
220
186
|
if (leading && !timer) {
|
|
221
187
|
callback(...args)
|
|
222
188
|
lastArgs = null
|
|
@@ -278,8 +244,7 @@ export const modifyViewTransition = (
|
|
|
278
244
|
): EventCallbackHandler => {
|
|
279
245
|
if (mods.has("viewtransition") && supportsViewTransitions) {
|
|
280
246
|
const cb = callback
|
|
281
|
-
callback = (...args: any
|
|
282
|
-
document.startViewTransition(() => cb(...args))
|
|
247
|
+
callback = (...args: Array<any>) => document.startViewTransition(() => cb(...args))
|
|
283
248
|
}
|
|
284
249
|
|
|
285
250
|
return callback
|