@remix-run/ui 0.7.0 → 0.8.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 +35 -7
- package/dist/animation/demos/drag-release.js +5 -7
- package/dist/animation/demos/drag-release.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/diff-dom.js +8 -3
- package/dist/runtime/diff-dom.js.map +1 -1
- package/dist/runtime/dom.d.ts +21 -11
- package/dist/runtime/event-types.d.ts +14 -0
- package/dist/runtime/event-types.js +2 -0
- package/dist/runtime/event-types.js.map +1 -0
- package/dist/runtime/frame-resolution.js +8 -0
- package/dist/runtime/frame-resolution.js.map +1 -1
- package/dist/runtime/frame.d.ts +5 -2
- package/dist/runtime/frame.js +107 -49
- package/dist/runtime/frame.js.map +1 -1
- package/dist/runtime/mixins/link-mixin.js +4 -4
- package/dist/runtime/mixins/link-mixin.js.map +1 -1
- package/dist/runtime/mixins/mixin.d.ts +9 -3
- package/dist/runtime/mixins/mixin.js.map +1 -1
- package/dist/runtime/mixins/on-mixin.d.ts +1 -1
- package/dist/runtime/module-preloader.js +3 -3
- package/dist/runtime/module-preloader.js.map +1 -1
- package/dist/runtime/navigation.js +114 -32
- package/dist/runtime/navigation.js.map +1 -1
- package/dist/runtime/reconcile.js +9 -3
- package/dist/runtime/reconcile.js.map +1 -1
- package/dist/runtime/run.js +5 -3
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/scheduler.js +37 -11
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/spa-response.d.ts +30 -0
- package/dist/runtime/spa-response.js +47 -0
- package/dist/runtime/spa-response.js.map +1 -0
- package/dist/runtime/typed-event-target.d.ts +0 -4
- package/dist/runtime/typed-event-target.js.map +1 -1
- package/dist/server/stream.js +21 -5
- package/dist/server/stream.js.map +1 -1
- package/dist/style/stylesheet.js +2 -2
- package/dist/style/stylesheet.js.map +1 -1
- package/package.json +1 -1
- package/src/animation/demos/drag-release.ts +5 -7
- package/src/index.ts +2 -2
- package/src/runtime/demos/readme.demo.tsx +7 -17
- package/src/runtime/diff-dom.ts +6 -3
- package/src/runtime/dom.ts +21 -11
- package/src/runtime/event-types.ts +27 -0
- package/src/runtime/frame-resolution.ts +9 -0
- package/src/runtime/frame.ts +112 -50
- package/src/runtime/mixins/link-mixin.ts +4 -4
- package/src/runtime/mixins/mixin.ts +26 -4
- package/src/runtime/mixins/on-mixin.ts +1 -1
- package/src/runtime/module-preloader.ts +3 -3
- package/src/runtime/navigation.ts +126 -31
- package/src/runtime/reconcile.ts +11 -4
- package/src/runtime/run.ts +6 -3
- package/src/runtime/scheduler.ts +53 -13
- package/src/runtime/spa-response.ts +56 -0
- package/src/runtime/typed-event-target.ts +1 -6
- package/src/server/stream.ts +28 -5
- package/src/style/stylesheet.ts +3 -3
- package/dist/runtime/event-listeners.d.ts +0 -50
- package/dist/runtime/event-listeners.js +0 -31
- package/dist/runtime/event-listeners.js.map +0 -1
- package/src/runtime/event-listeners.ts +0 -171
package/src/runtime/frame.ts
CHANGED
|
@@ -170,7 +170,9 @@ export type FrameRuntime = {
|
|
|
170
170
|
moduleLoads: Map<string, Promise<ElementFunction | undefined>>
|
|
171
171
|
frameInstances: WeakMap<Comment, Frame>
|
|
172
172
|
namedFrames: Map<string, FrameHandle>
|
|
173
|
-
serverFrameReload:
|
|
173
|
+
serverFrameReload:
|
|
174
|
+
| { signal: AbortSignal; reconciliationTracker?: ReconciliationTracker }
|
|
175
|
+
| undefined
|
|
174
176
|
reloadForNavigation?: (options?: FrameReloadOptions) => Promise<FrameReloadResult>
|
|
175
177
|
}
|
|
176
178
|
|
|
@@ -215,6 +217,7 @@ export type FrameContext = {
|
|
|
215
217
|
regionParent?: ParentNode | null
|
|
216
218
|
signal?: AbortSignal
|
|
217
219
|
isActiveModulePreload?: (node: Node) => boolean
|
|
220
|
+
reconciliationTracker?: ReconciliationTracker
|
|
218
221
|
}
|
|
219
222
|
|
|
220
223
|
type FrameInit = {
|
|
@@ -260,7 +263,7 @@ export type Frame = {
|
|
|
260
263
|
|
|
261
264
|
type RenderOptions = {
|
|
262
265
|
flushKind?: FlushKind
|
|
263
|
-
|
|
266
|
+
reconciliationTracker?: ReconciliationTracker
|
|
264
267
|
signal?: AbortSignal
|
|
265
268
|
contentStatus?: 'pending' | 'resolved'
|
|
266
269
|
data?: RmxData
|
|
@@ -385,7 +388,22 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
385
388
|
}
|
|
386
389
|
|
|
387
390
|
if (isRenderAborted(options.signal)) return
|
|
388
|
-
|
|
391
|
+
let previousServerFrameReload = runtime.serverFrameReload
|
|
392
|
+
if (options.signal) {
|
|
393
|
+
runtime.serverFrameReload = {
|
|
394
|
+
signal: options.signal,
|
|
395
|
+
reconciliationTracker: options.reconciliationTracker,
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
try {
|
|
400
|
+
contentRoot.render(content)
|
|
401
|
+
await new Promise<void>((resolve) => context.scheduler.enqueueCommitPhase([resolve]))
|
|
402
|
+
} finally {
|
|
403
|
+
runtime.serverFrameReload = previousServerFrameReload
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (isRenderAborted(options.signal)) return
|
|
389
407
|
displayedContentStatus = options.contentStatus ?? 'resolved'
|
|
390
408
|
return
|
|
391
409
|
}
|
|
@@ -419,7 +437,11 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
419
437
|
modulePreloader.consumePreloadLinks(parsed)
|
|
420
438
|
let responseData = options.data
|
|
421
439
|
mergeRmxDataFromDocument(responseData, parsed)
|
|
422
|
-
let responseContext = {
|
|
440
|
+
let responseContext = {
|
|
441
|
+
...context,
|
|
442
|
+
data: responseData,
|
|
443
|
+
reconciliationTracker: options.reconciliationTracker,
|
|
444
|
+
}
|
|
423
445
|
context.styleManager.adoptServerStyles(
|
|
424
446
|
collectFrameServerStyleTags(createElementContainer(parsed)),
|
|
425
447
|
)
|
|
@@ -447,7 +469,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
447
469
|
scheduleHydrationInContainer(
|
|
448
470
|
bodyContainer,
|
|
449
471
|
responseContext,
|
|
450
|
-
options.
|
|
472
|
+
options.reconciliationTracker,
|
|
451
473
|
options.signal,
|
|
452
474
|
)
|
|
453
475
|
await createSubFrames(bodyContainer.childNodes, responseContext, options)
|
|
@@ -465,7 +487,11 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
465
487
|
removeEmptyHeads(fragment)
|
|
466
488
|
let responseData = options.data
|
|
467
489
|
mergeRmxDataFromFragment(responseData, fragment)
|
|
468
|
-
let responseContext = {
|
|
490
|
+
let responseContext = {
|
|
491
|
+
...context,
|
|
492
|
+
data: responseData,
|
|
493
|
+
reconciliationTracker: options.reconciliationTracker,
|
|
494
|
+
}
|
|
469
495
|
|
|
470
496
|
let nextContainer = createContainer(fragment)
|
|
471
497
|
|
|
@@ -478,11 +504,10 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
478
504
|
signal: options.signal,
|
|
479
505
|
})
|
|
480
506
|
|
|
481
|
-
if (isRenderAborted(options.signal)) return
|
|
482
507
|
scheduleHydrationInContainer(
|
|
483
508
|
container,
|
|
484
509
|
responseContext,
|
|
485
|
-
options.
|
|
510
|
+
options.reconciliationTracker,
|
|
486
511
|
options.signal,
|
|
487
512
|
)
|
|
488
513
|
await createSubFrames(container.childNodes, responseContext, options)
|
|
@@ -532,11 +557,11 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
532
557
|
}
|
|
533
558
|
|
|
534
559
|
async function hydrateInitial(): Promise<void> {
|
|
535
|
-
let
|
|
560
|
+
let reconciliationTracker = createReconciliationTracker()
|
|
536
561
|
|
|
537
562
|
context.styleManager.adoptServerStyles(collectFrameServerStyleTags(container))
|
|
538
563
|
let subFramesReady = createSubFrames(container.childNodes, context)
|
|
539
|
-
scheduleHydrationInContainer(container, context,
|
|
564
|
+
scheduleHydrationInContainer(container, context, reconciliationTracker)
|
|
540
565
|
|
|
541
566
|
try {
|
|
542
567
|
await subFramesReady
|
|
@@ -544,11 +569,11 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
544
569
|
if (disposed || context.lifecycleSignal.aborted) return
|
|
545
570
|
|
|
546
571
|
if (currentMarker?.status === 'pending') {
|
|
547
|
-
await watchPendingFrameTemplate(currentMarker,
|
|
572
|
+
await watchPendingFrameTemplate(currentMarker, reconciliationTracker)
|
|
548
573
|
}
|
|
549
574
|
|
|
550
|
-
|
|
551
|
-
await
|
|
575
|
+
reconciliationTracker.finalize()
|
|
576
|
+
await reconciliationTracker.ready()
|
|
552
577
|
} finally {
|
|
553
578
|
clearRmxData(context.data)
|
|
554
579
|
}
|
|
@@ -615,7 +640,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
615
640
|
if (marker.status === 'pending') {
|
|
616
641
|
await watchPendingFrameTemplate(
|
|
617
642
|
marker,
|
|
618
|
-
options?.
|
|
643
|
+
options?.reconciliationTracker,
|
|
619
644
|
options?.signal,
|
|
620
645
|
isInheritedReload
|
|
621
646
|
? () => {
|
|
@@ -736,7 +761,13 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
736
761
|
if (reloadController !== controller || controller.signal.aborted) {
|
|
737
762
|
return { signal: controller.signal }
|
|
738
763
|
}
|
|
739
|
-
|
|
764
|
+
let reconciliationTracker = createReconciliationTracker()
|
|
765
|
+
await render(content, {
|
|
766
|
+
signal: controller.signal,
|
|
767
|
+
reconciliationTracker,
|
|
768
|
+
})
|
|
769
|
+
reconciliationTracker.finalize()
|
|
770
|
+
await reconciliationTracker.ready()
|
|
740
771
|
return {
|
|
741
772
|
signal: controller.signal,
|
|
742
773
|
redirectedTo:
|
|
@@ -825,7 +856,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
825
856
|
|
|
826
857
|
async function watchPendingFrameTemplate(
|
|
827
858
|
marker: FrameMarkerData,
|
|
828
|
-
|
|
859
|
+
reconciliationTracker?: ReconciliationTracker,
|
|
829
860
|
signal?: AbortSignal,
|
|
830
861
|
onResolved?: () => void,
|
|
831
862
|
): Promise<void> {
|
|
@@ -838,7 +869,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
838
869
|
let early = consumeFrameTemplate(marker.id) ?? getEarlyFrameContent(marker.id)
|
|
839
870
|
if (early) {
|
|
840
871
|
clearPendingFrameTemplateWatch()
|
|
841
|
-
await render(early, {
|
|
872
|
+
await render(early, { reconciliationTracker, signal, contentStatus: 'resolved' })
|
|
842
873
|
if (!disposed && !context.lifecycleSignal.aborted && !signal?.aborted) onResolved?.()
|
|
843
874
|
return
|
|
844
875
|
}
|
|
@@ -872,7 +903,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
|
|
|
872
903
|
let buffered = consumeFrameTemplate(marker.id)
|
|
873
904
|
if (buffered) {
|
|
874
905
|
clearPendingFrameTemplateWatch()
|
|
875
|
-
await render(buffered, {
|
|
906
|
+
await render(buffered, { reconciliationTracker, signal, contentStatus: 'resolved' })
|
|
876
907
|
if (!disposed && !context.lifecycleSignal.aborted && !signal?.aborted) onResolved?.()
|
|
877
908
|
}
|
|
878
909
|
}
|
|
@@ -910,42 +941,60 @@ export function createFrameRuntime(init: {
|
|
|
910
941
|
}
|
|
911
942
|
}
|
|
912
943
|
|
|
913
|
-
type
|
|
944
|
+
export type ReconciliationTracker = {
|
|
914
945
|
track: () => () => void
|
|
946
|
+
waitFor: (task: Promise<void>) => void
|
|
915
947
|
finalize: () => void
|
|
916
948
|
ready: () => Promise<void>
|
|
917
949
|
}
|
|
918
950
|
|
|
919
|
-
function
|
|
951
|
+
function createReconciliationTracker(): ReconciliationTracker {
|
|
920
952
|
let pending = 0
|
|
921
953
|
let finalized = false
|
|
954
|
+
let failed = false
|
|
955
|
+
let failure: unknown
|
|
922
956
|
|
|
923
957
|
let resolveReady: (() => void) | undefined
|
|
924
|
-
let
|
|
958
|
+
let rejectReady: ((error: unknown) => void) | undefined
|
|
959
|
+
let readyPromise = new Promise<void>((resolve, reject) => {
|
|
925
960
|
resolveReady = resolve
|
|
961
|
+
rejectReady = reject
|
|
926
962
|
})
|
|
927
963
|
|
|
928
|
-
function
|
|
929
|
-
if (finalized
|
|
930
|
-
|
|
931
|
-
|
|
964
|
+
function maybeSettle() {
|
|
965
|
+
if (!finalized || pending !== 0) return
|
|
966
|
+
if (failed) rejectReady?.(failure)
|
|
967
|
+
else resolveReady?.()
|
|
968
|
+
resolveReady = undefined
|
|
969
|
+
rejectReady = undefined
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function track(): () => void {
|
|
973
|
+
pending++
|
|
974
|
+
let completed = false
|
|
975
|
+
return () => {
|
|
976
|
+
if (completed) return
|
|
977
|
+
completed = true
|
|
978
|
+
pending--
|
|
979
|
+
maybeSettle()
|
|
932
980
|
}
|
|
933
981
|
}
|
|
934
982
|
|
|
935
983
|
return {
|
|
936
|
-
track
|
|
937
|
-
|
|
938
|
-
let
|
|
939
|
-
|
|
940
|
-
if (
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
984
|
+
track,
|
|
985
|
+
waitFor(task) {
|
|
986
|
+
let complete = track()
|
|
987
|
+
void task.then(complete, (error) => {
|
|
988
|
+
if (!failed) {
|
|
989
|
+
failed = true
|
|
990
|
+
failure = error
|
|
991
|
+
}
|
|
992
|
+
complete()
|
|
993
|
+
})
|
|
945
994
|
},
|
|
946
995
|
finalize() {
|
|
947
996
|
finalized = true
|
|
948
|
-
|
|
997
|
+
maybeSettle()
|
|
949
998
|
},
|
|
950
999
|
ready() {
|
|
951
1000
|
return readyPromise
|
|
@@ -1006,7 +1055,7 @@ function collectOwnedServerStyleTags(nodes: Node[], styles: HTMLStyleElement[]):
|
|
|
1006
1055
|
continue
|
|
1007
1056
|
}
|
|
1008
1057
|
|
|
1009
|
-
if (node instanceof HTMLStyleElement && node.matches('style[data-rmx]')) {
|
|
1058
|
+
if (node instanceof HTMLStyleElement && node.matches('style[data-rmx-style]')) {
|
|
1010
1059
|
styles.push(node)
|
|
1011
1060
|
continue
|
|
1012
1061
|
}
|
|
@@ -1049,7 +1098,7 @@ function copyOwnRmxEntries<T>(target: Record<string, T>, source: Record<string,
|
|
|
1049
1098
|
function scheduleHydrationInContainer(
|
|
1050
1099
|
container: FrameContainer,
|
|
1051
1100
|
context: FrameContext,
|
|
1052
|
-
|
|
1101
|
+
reconciliationTracker?: ReconciliationTracker,
|
|
1053
1102
|
signal?: AbortSignal,
|
|
1054
1103
|
): void {
|
|
1055
1104
|
let hydrationMarkers = findHydrationMarkers(container)
|
|
@@ -1061,7 +1110,7 @@ function scheduleHydrationInContainer(
|
|
|
1061
1110
|
for (let marker of hydrationMarkers) {
|
|
1062
1111
|
let entry = hydrationData[marker.id]
|
|
1063
1112
|
if (!entry) continue
|
|
1064
|
-
scheduleHydrationMarker(marker, entry, context,
|
|
1113
|
+
scheduleHydrationMarker(marker, entry, context, reconciliationTracker, signal)
|
|
1065
1114
|
}
|
|
1066
1115
|
}
|
|
1067
1116
|
|
|
@@ -1069,12 +1118,12 @@ function scheduleHydrationMarker(
|
|
|
1069
1118
|
marker: HydrationMarker,
|
|
1070
1119
|
entry: HydrationData,
|
|
1071
1120
|
context: FrameContext,
|
|
1072
|
-
|
|
1121
|
+
reconciliationTracker?: ReconciliationTracker,
|
|
1073
1122
|
signal?: AbortSignal,
|
|
1074
1123
|
): void {
|
|
1075
1124
|
if (signal?.aborted || context.lifecycleSignal.aborted) return
|
|
1076
1125
|
|
|
1077
|
-
let done =
|
|
1126
|
+
let done = reconciliationTracker?.track()
|
|
1078
1127
|
let key = `${entry.moduleUrl}#${entry.exportName}`
|
|
1079
1128
|
let identity: ClientEntryIdentity = {
|
|
1080
1129
|
moduleUrl: entry.moduleUrl,
|
|
@@ -1216,30 +1265,40 @@ function hydrateRegion(
|
|
|
1216
1265
|
|
|
1217
1266
|
context.pendingClientEntries.delete(start)
|
|
1218
1267
|
|
|
1219
|
-
//
|
|
1220
|
-
//
|
|
1221
|
-
//
|
|
1222
|
-
let
|
|
1223
|
-
if (owner) {
|
|
1268
|
+
// During a server frame reload, expose the reload signal and reconciliation
|
|
1269
|
+
// tracker to client frames created while this entry renders so blocking
|
|
1270
|
+
// frames keep the reload pending until their content arrives.
|
|
1271
|
+
let renderEntry = (root: Pick<VirtualRoot, 'render'>) => {
|
|
1224
1272
|
if (!signal) {
|
|
1225
|
-
|
|
1273
|
+
root.render(vElement)
|
|
1226
1274
|
return
|
|
1227
1275
|
}
|
|
1228
1276
|
|
|
1229
1277
|
let frameRuntime = context.frame.$runtime
|
|
1230
1278
|
invariant(
|
|
1231
1279
|
isFrameRuntime(frameRuntime),
|
|
1232
|
-
'Expected frame runtime while rendering a
|
|
1280
|
+
'Expected frame runtime while rendering a client entry during a reload',
|
|
1233
1281
|
)
|
|
1234
1282
|
|
|
1235
1283
|
let previousServerFrameReload = frameRuntime.serverFrameReload
|
|
1236
1284
|
|
|
1237
|
-
frameRuntime.serverFrameReload = {
|
|
1285
|
+
frameRuntime.serverFrameReload = {
|
|
1286
|
+
signal,
|
|
1287
|
+
reconciliationTracker: context.reconciliationTracker,
|
|
1288
|
+
}
|
|
1238
1289
|
try {
|
|
1239
|
-
|
|
1290
|
+
root.render(vElement)
|
|
1240
1291
|
} finally {
|
|
1241
1292
|
frameRuntime.serverFrameReload = previousServerFrameReload
|
|
1242
1293
|
}
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
// The same marker can be discovered by overlapping hydration passes
|
|
1297
|
+
// (for example, document root + nested frame root). Reuse the existing
|
|
1298
|
+
// virtual root instead of redefining the marker property.
|
|
1299
|
+
let owner = getClientEntryBoundaryOwner(start)
|
|
1300
|
+
if (owner) {
|
|
1301
|
+
renderEntry(owner.root)
|
|
1243
1302
|
return
|
|
1244
1303
|
}
|
|
1245
1304
|
|
|
@@ -1254,7 +1313,7 @@ function hydrateRegion(
|
|
|
1254
1313
|
})
|
|
1255
1314
|
|
|
1256
1315
|
setClientEntryBoundaryOwner(start, identity, root)
|
|
1257
|
-
root
|
|
1316
|
+
renderEntry(root)
|
|
1258
1317
|
}
|
|
1259
1318
|
|
|
1260
1319
|
async function createSubFrames(
|
|
@@ -1302,6 +1361,9 @@ async function createSubFrames(
|
|
|
1302
1361
|
namedFrames: context.namedFrames,
|
|
1303
1362
|
})
|
|
1304
1363
|
context.frameInstances.set(node, subFrame)
|
|
1364
|
+
if (frameMarker.status === 'resolved') {
|
|
1365
|
+
tasks.push(subFrame.ready())
|
|
1366
|
+
}
|
|
1305
1367
|
}
|
|
1306
1368
|
}
|
|
1307
1369
|
|
|
@@ -34,10 +34,10 @@ export const link: MixinFactory<
|
|
|
34
34
|
return renderMixinElement(handle.element, {
|
|
35
35
|
...(props ?? {}),
|
|
36
36
|
href,
|
|
37
|
-
...(options?.target == null ? {} : { 'rmx-target': options.target }),
|
|
38
|
-
...(options?.src == null ? {} : { 'rmx-src': options.src }),
|
|
39
|
-
...(options?.history == null ? {} : { 'rmx-history': options.history }),
|
|
40
|
-
...(options?.resetScroll === false ? { 'rmx-reset-scroll': 'false' } : {}),
|
|
37
|
+
...(options?.target == null ? {} : { 'data-rmx-target': options.target }),
|
|
38
|
+
...(options?.src == null ? {} : { 'data-rmx-src': options.src }),
|
|
39
|
+
...(options?.history == null ? {} : { 'data-rmx-history': options.history }),
|
|
40
|
+
...(options?.resetScroll === false ? { 'data-rmx-reset-scroll': 'false' } : {}),
|
|
41
41
|
})
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -107,6 +107,15 @@ type MixinRuntimeType<
|
|
|
107
107
|
type: string,
|
|
108
108
|
) => ((...args: [...args, currentProps: props]) => MixinReturn<node, props>) | void
|
|
109
109
|
|
|
110
|
+
type MixinDescriptorType<
|
|
111
|
+
args extends unknown[] = [],
|
|
112
|
+
node extends EventTarget = Element,
|
|
113
|
+
props extends ElementProps = ElementProps,
|
|
114
|
+
> = <boundNode extends node>(
|
|
115
|
+
handle: MixinHandle<boundNode, props>,
|
|
116
|
+
type: string,
|
|
117
|
+
) => ((...args: [...args, currentProps: props]) => MixinReturn<boundNode, props>) | void
|
|
118
|
+
|
|
110
119
|
/**
|
|
111
120
|
* Public mixin setup function signature.
|
|
112
121
|
*/
|
|
@@ -127,7 +136,7 @@ export type MixinDescriptor<
|
|
|
127
136
|
args extends unknown[] = [],
|
|
128
137
|
props extends ElementProps = ElementProps,
|
|
129
138
|
> = {
|
|
130
|
-
type:
|
|
139
|
+
type: MixinDescriptorType<args, node, props>
|
|
131
140
|
args: args
|
|
132
141
|
readonly __node?: (node: node) => void
|
|
133
142
|
}
|
|
@@ -149,13 +158,22 @@ type NestedMixValue<descriptor, depth extends number = 4> = depth extends 0
|
|
|
149
158
|
| NullableMixValue<descriptor>
|
|
150
159
|
| ReadonlyArray<NestedMixValue<descriptor, PreviousMixDepth[depth]>>
|
|
151
160
|
|
|
161
|
+
type MixinInputDescriptor<
|
|
162
|
+
in node extends EventTarget = Element,
|
|
163
|
+
props extends ElementProps = ElementProps,
|
|
164
|
+
> = {
|
|
165
|
+
type: (handle: MixinHandle<node, props>, type: string) => unknown
|
|
166
|
+
args: readonly unknown[]
|
|
167
|
+
readonly __node?: (node: node) => void
|
|
168
|
+
}
|
|
169
|
+
|
|
152
170
|
/**
|
|
153
171
|
* Accepted authoring shape for the `mix` prop on host elements.
|
|
154
172
|
*/
|
|
155
173
|
export type MixInput<
|
|
156
174
|
node extends EventTarget = Element,
|
|
157
175
|
props extends ElementProps = ElementProps,
|
|
158
|
-
> = NestedMixValue<
|
|
176
|
+
> = NestedMixValue<MixinInputDescriptor<node, props>>
|
|
159
177
|
|
|
160
178
|
/**
|
|
161
179
|
* Accepted value shape for the `mix` prop.
|
|
@@ -163,7 +181,7 @@ export type MixInput<
|
|
|
163
181
|
export type MixValue<
|
|
164
182
|
node extends EventTarget = Element,
|
|
165
183
|
props extends ElementProps = ElementProps,
|
|
166
|
-
> =
|
|
184
|
+
> = MixinInputDescriptor<node, props> | ReadonlyArray<MixinInputDescriptor<node, props>>
|
|
167
185
|
|
|
168
186
|
type MixinReturn<node extends EventTarget = Element, props extends ElementProps = ElementProps> =
|
|
169
187
|
| void
|
|
@@ -259,7 +277,11 @@ export function createMixin<
|
|
|
259
277
|
return <boundNode extends node = node>(
|
|
260
278
|
...args: RebindTuple<args, node, boundNode>
|
|
261
279
|
): MixinDescriptor<boundNode, RebindTuple<args, node, boundNode>, props> => ({
|
|
262
|
-
type: type as unknown as
|
|
280
|
+
type: type as unknown as MixinDescriptorType<
|
|
281
|
+
RebindTuple<args, node, boundNode>,
|
|
282
|
+
boundNode,
|
|
283
|
+
props
|
|
284
|
+
>,
|
|
263
285
|
args: args as RebindTuple<args, node, boundNode>,
|
|
264
286
|
})
|
|
265
287
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createMixin, type MixinType } from './mixin.ts'
|
|
2
2
|
import type { ElementProps } from '../jsx.ts'
|
|
3
3
|
import type { MixinDescriptor } from './mixin.ts'
|
|
4
|
-
import type { EnsureEvent, EventMap } from '../event-
|
|
4
|
+
import type { EnsureEvent, EventMap } from '../event-types.ts'
|
|
5
5
|
|
|
6
6
|
type SignaledListener<event extends Event> = (
|
|
7
7
|
event: event,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const SERVER_MODULE_PRELOAD_SELECTOR = 'link[data-rmx][rel~="modulepreload" i][href]'
|
|
1
|
+
const SERVER_MODULE_PRELOAD_SELECTOR = 'link[data-rmx-module-preload][rel~="modulepreload" i][href]'
|
|
2
2
|
|
|
3
3
|
interface ModulePreloader {
|
|
4
4
|
adoptInitialPreloadLinks(source: ParentNode): void
|
|
@@ -36,7 +36,7 @@ function createModulePreloader(doc: Document): ModulePreloader {
|
|
|
36
36
|
let link = doc.createElement('link')
|
|
37
37
|
link.rel = 'modulepreload'
|
|
38
38
|
link.href = href
|
|
39
|
-
link.setAttribute('data-rmx', '')
|
|
39
|
+
link.setAttribute('data-rmx-module-preload', '')
|
|
40
40
|
let url = link.href
|
|
41
41
|
if (requestedUrls.has(url)) return
|
|
42
42
|
requestedUrls.add(url)
|
|
@@ -74,7 +74,7 @@ function createModulePreloader(doc: Document): ModulePreloader {
|
|
|
74
74
|
let observerLink = doc.createElement('link')
|
|
75
75
|
observerLink.rel = 'modulepreload'
|
|
76
76
|
observerLink.href = initialLink.href
|
|
77
|
-
observerLink.setAttribute('data-rmx', '')
|
|
77
|
+
observerLink.setAttribute('data-rmx-module-preload', '')
|
|
78
78
|
let url = initialLink.href
|
|
79
79
|
requestedUrls.add(url)
|
|
80
80
|
activateLink(initialLink)
|