foldkit 0.167.0 → 0.168.0-canary.1ce3d4b05055
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/calendar/calendarDate.d.ts.map +1 -1
- package/dist/calendar/calendarDate.js +1 -1
- package/dist/experimental/server/fragment.d.ts +15 -0
- package/dist/experimental/server/fragment.d.ts.map +1 -0
- package/dist/experimental/server/fragment.js +14 -0
- package/dist/experimental/server/server.d.ts +3 -2
- package/dist/experimental/server/server.d.ts.map +1 -1
- package/dist/experimental/server/server.js +20 -23
- package/dist/experimental/server/template.d.ts.map +1 -1
- package/dist/experimental/server/template.js +20 -19
- package/dist/runtime/hydrationHandoff.d.ts.map +1 -1
- package/dist/runtime/hydrationHandoff.js +4 -2
- package/dist/runtime/runtime.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendarDate.d.ts","sourceRoot":"","sources":["../../src/calendar/calendarDate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAqC,MAAM,QAAQ,CAAA;AAE1E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,OACgB,CAAA;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,SAAU,MAAM,SAAS,MAAM,KAAG,MAQzD,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY;;;;EAcxB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,YACjC,CAAA;AAEzB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI,SAAU,MAAM,SAAS,MAAM,OAAO,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"calendarDate.d.ts","sourceRoot":"","sources":["../../src/calendar/calendarDate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAqC,MAAM,QAAQ,CAAA;AAE1E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,OACgB,CAAA;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,SAAU,MAAM,SAAS,MAAM,KAAG,MAQzD,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY;;;;EAcxB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,YACjC,CAAA;AAEzB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI,SAAU,MAAM,SAAS,MAAM,OAAO,MAAM,KAAG,YACT,CAAA;AAEvD;;;;GAIG;AACH,eAAO,MAAM,UAAU,SACf,MAAM,SACL,MAAM,OACR,MAAM,KACV,YAC+D,CAAA;AAElE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,SAAU,IAAI,KAAG,YAC0B,CAAA;AAErE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,SAAU,IAAI,YAAY,MAAM,KAAG,YAa7D,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,iBAAkB,YAAY,KAAG,IACc,CAAA;AAIvE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,yBAAyB;;;;gCA0BrC,CAAA"}
|
|
@@ -96,7 +96,7 @@ export const isCalendarDate = Schema.is(CalendarDate);
|
|
|
96
96
|
* Calendar.make(2026, 2, 29) // throws — not a leap year
|
|
97
97
|
* ```
|
|
98
98
|
*/
|
|
99
|
-
export const make = (year, month, day) => Schema.
|
|
99
|
+
export const make = (year, month, day) => Schema.decodeSync(CalendarDate)({ year, month, day });
|
|
100
100
|
/**
|
|
101
101
|
* Constructs a `CalendarDate` without Schema validation. Only for inputs the
|
|
102
102
|
* caller knows are valid — typically arithmetic results inside the calendar
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DefaultTreeAdapterMap } from 'parse5';
|
|
2
|
+
/** The same rendered fragment parsed with scripting enabled and disabled.
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export type ParsedFragmentModes = Readonly<{
|
|
6
|
+
scripted: DefaultTreeAdapterMap['documentFragment'];
|
|
7
|
+
unscripted: DefaultTreeAdapterMap['documentFragment'];
|
|
8
|
+
}>;
|
|
9
|
+
/** Parses both scripting modes in the supplied HTML insertion context.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const parseFragmentModes: (context: DefaultTreeAdapterMap['element'], html: string, options?: Readonly<{
|
|
13
|
+
sourceCodeLocationInfo?: boolean;
|
|
14
|
+
}>) => ParsedFragmentModes;
|
|
15
|
+
//# sourceMappingURL=fragment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fragment.d.ts","sourceRoot":"","sources":["../../../src/experimental/server/fragment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAA;AAGnD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,QAAQ,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;IACnD,UAAU,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;CACtD,CAAC,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,YACpB,qBAAqB,CAAC,SAAS,CAAC,QACnC,MAAM,YACH,QAAQ,CAAC;IAAE,sBAAsB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KACtD,mBASD,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { parseFragment } from 'parse5';
|
|
2
|
+
/** Parses both scripting modes in the supplied HTML insertion context.
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export const parseFragmentModes = (context, html, options = {}) => ({
|
|
6
|
+
scripted: parseFragment(context, html, {
|
|
7
|
+
...options,
|
|
8
|
+
scriptingEnabled: true,
|
|
9
|
+
}),
|
|
10
|
+
unscripted: parseFragment(context, html, {
|
|
11
|
+
...options,
|
|
12
|
+
scriptingEnabled: false,
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
@@ -3,8 +3,9 @@ import { type Document, type HtmlBuilder } from '../../html/index.js';
|
|
|
3
3
|
import { FOLDKIT_APP_ATTRIBUTE, FOLDKIT_FLAGS_ATTRIBUTE } from '../../hydrationMarker.js';
|
|
4
4
|
import type { Return as UpdateReturn } from '../../update/index.js';
|
|
5
5
|
import { Url } from '../../url/index.js';
|
|
6
|
-
|
|
7
|
-
export declare const
|
|
6
|
+
import { type ParsedFragmentModes } from './fragment.js';
|
|
7
|
+
export declare const __assertNoDeclarativeShadowRoot: (fragments: ParsedFragmentModes) => void;
|
|
8
|
+
export declare const __assertNoLiveBaseElement: (fragments: ParsedFragmentModes) => void;
|
|
8
9
|
export declare const __assertNoDocumentStructureEscape: (html: string) => void;
|
|
9
10
|
export { FOLDKIT_APP_ATTRIBUTE, FOLDKIT_FLAGS_ATTRIBUTE };
|
|
10
11
|
/** The server render of one request: the body markup and the `Document` head
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/experimental/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,MAAM,EAGN,MAAM,EAGP,MAAM,QAAQ,CAAA;AAmBf,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,WAAW,EAGjB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,0BAA0B,CAAA;AAQjC,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAE,GAAG,EAAc,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/experimental/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ import { HYDRATION_IDENTITY_ATTRIBUTE, HYDRATION_KEY_ATTRIBUTE, } from '../../hy
|
|
|
10
10
|
import { hasTrustedInnerHtml } from '../../propertyProvenance.js';
|
|
11
11
|
import { tagNameFromSelector } from '../../tagName.js';
|
|
12
12
|
import { fromString } from '../../url/index.js';
|
|
13
|
+
import { parseFragmentModes } from './fragment.js';
|
|
13
14
|
import { controlledValueContent, escapeAttributeValue, serializeHtml, } from './serialize.js';
|
|
14
15
|
const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
|
|
15
16
|
const isParse5Element = (node) => 'tagName' in node;
|
|
@@ -352,14 +353,8 @@ const assertInnerHtmlContextMatches = (parsed, vnode) => {
|
|
|
352
353
|
'tree. Move the fragment outside that context or build the content with ' +
|
|
353
354
|
'ordinary view children.');
|
|
354
355
|
};
|
|
355
|
-
const assertNoscriptModesAgree = (
|
|
356
|
-
|
|
357
|
-
scriptingEnabled: true,
|
|
358
|
-
});
|
|
359
|
-
const unscripted = parseFragment(DIV_FRAGMENT_CONTEXT, html, {
|
|
360
|
-
scriptingEnabled: false,
|
|
361
|
-
});
|
|
362
|
-
if (parsedChildrenAgree(scripted, unscripted)) {
|
|
356
|
+
const assertNoscriptModesAgree = (fragments) => {
|
|
357
|
+
if (parsedChildrenAgree(fragments.scripted, fragments.unscripted)) {
|
|
363
358
|
return;
|
|
364
359
|
}
|
|
365
360
|
throw new Error('[foldkit] <noscript> content changes the rest of the page when a browser ' +
|
|
@@ -397,8 +392,9 @@ const declaresShadowRoot = (element) => element.tagName.toLowerCase() === 'templ
|
|
|
397
392
|
const hasDeclarativeShadowRoot = (node) => node.childNodes.some(child => isParse5Element(child) &&
|
|
398
393
|
(declaresShadowRoot(child) ||
|
|
399
394
|
hasDeclarativeShadowRoot(traversableContent(child))));
|
|
400
|
-
export const __assertNoDeclarativeShadowRoot = (
|
|
401
|
-
const declaresInEitherMode =
|
|
395
|
+
export const __assertNoDeclarativeShadowRoot = (fragments) => {
|
|
396
|
+
const declaresInEitherMode = hasDeclarativeShadowRoot(fragments.scripted) ||
|
|
397
|
+
hasDeclarativeShadowRoot(fragments.unscripted);
|
|
402
398
|
if (!declaresInEitherMode) {
|
|
403
399
|
return;
|
|
404
400
|
}
|
|
@@ -432,8 +428,9 @@ const hasLiveBaseElement = (node) => {
|
|
|
432
428
|
}
|
|
433
429
|
return false;
|
|
434
430
|
};
|
|
435
|
-
export const __assertNoLiveBaseElement = (
|
|
436
|
-
const hasBaseInEitherMode =
|
|
431
|
+
export const __assertNoLiveBaseElement = (fragments) => {
|
|
432
|
+
const hasBaseInEitherMode = hasLiveBaseElement(fragments.scripted) ||
|
|
433
|
+
hasLiveBaseElement(fragments.unscripted);
|
|
437
434
|
if (!hasBaseInEitherMode) {
|
|
438
435
|
return;
|
|
439
436
|
}
|
|
@@ -643,8 +640,7 @@ const assertNoReservedHandoffMarkers = (root) => {
|
|
|
643
640
|
// invariant that the served root parses back to the single intended element.
|
|
644
641
|
// The single element the served markup parses back to, or a refusal naming what
|
|
645
642
|
// the parser did to it instead.
|
|
646
|
-
const parsedRootOf = (
|
|
647
|
-
const fragment = parseFragment(DIV_FRAGMENT_CONTEXT, html, {});
|
|
643
|
+
const parsedRootOf = (fragment, root) => {
|
|
648
644
|
const significant = fragment.childNodes.filter(node => !isIgnorableText(node));
|
|
649
645
|
const only = significant[0];
|
|
650
646
|
if (significant.length !== 1 ||
|
|
@@ -681,13 +677,13 @@ const parsedRootOf = (html, root) => {
|
|
|
681
677
|
// reshaped subtree, so without it a dropped subtree is simply lost, with nothing
|
|
682
678
|
// left to notice. What stays conditional is the marker check below: only a
|
|
683
679
|
// hydratable render emits a stamp for the parser to move.
|
|
684
|
-
const assertParsedRootMatchesView = (
|
|
685
|
-
const parsed = parsedRootOf(
|
|
680
|
+
const assertParsedRootMatchesView = (fragment, root) => {
|
|
681
|
+
const parsed = parsedRootOf(fragment, root);
|
|
686
682
|
assertNoReservedHandoffMarkers(parsed);
|
|
687
683
|
assertStructureMatches(parsed, root);
|
|
688
684
|
};
|
|
689
|
-
const assertSingleStampedRoot = (
|
|
690
|
-
const only = parsedRootOf(
|
|
685
|
+
const assertSingleStampedRoot = (fragment, runtimeId, buildId, root) => {
|
|
686
|
+
const only = parsedRootOf(fragment, root);
|
|
691
687
|
const applicationMarkers = elementsCarrying(only, FOLDKIT_APP_ATTRIBUTE);
|
|
692
688
|
const buildMarkers = elementsCarrying(only, HYDRATION_BUILD_ATTRIBUTE);
|
|
693
689
|
const flagsMarkers = elementsCarrying(only, FOLDKIT_FLAGS_ATTRIBUTE);
|
|
@@ -895,16 +891,17 @@ export function renderToString(config, options) {
|
|
|
895
891
|
// is placed into a document the same way, so a root that does not close
|
|
896
892
|
// cleanly swallows whatever the host writes after it either way.
|
|
897
893
|
assertRootClosesCleanly(html);
|
|
898
|
-
|
|
899
|
-
|
|
894
|
+
const fragments = parseFragmentModes(DIV_FRAGMENT_CONTEXT, html);
|
|
895
|
+
assertNoscriptModesAgree(fragments);
|
|
896
|
+
__assertNoDeclarativeShadowRoot(fragments);
|
|
900
897
|
__assertNoDocumentStructureEscape(html);
|
|
901
|
-
__assertNoLiveBaseElement(
|
|
898
|
+
__assertNoLiveBaseElement(fragments);
|
|
902
899
|
if (nextDocument.body !== null) {
|
|
903
900
|
if (isHydratable) {
|
|
904
|
-
assertSingleStampedRoot(
|
|
901
|
+
assertSingleStampedRoot(fragments.scripted, runtimeId, buildId, nextDocument.body);
|
|
905
902
|
}
|
|
906
903
|
else {
|
|
907
|
-
assertParsedRootMatchesView(
|
|
904
|
+
assertParsedRootMatchesView(fragments.scripted, nextDocument.body);
|
|
908
905
|
}
|
|
909
906
|
}
|
|
910
907
|
return html;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/experimental/server/template.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/experimental/server/template.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,mBAAmB,EAIzB,MAAM,aAAa,CAAA;AAyoBpB;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C;iDAC6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,kBAAkB,aACnB,MAAM,YACN,mBAAmB,YACnB,yBAAyB,KAClC,MAkOF,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { html as Parse5Html, defaultTreeAdapter, parse
|
|
1
|
+
import { html as Parse5Html, defaultTreeAdapter, parse } from 'parse5';
|
|
2
2
|
import { HYDRATION_BUILD_ATTRIBUTE } from '../../buildToken.js';
|
|
3
3
|
import { FOLDKIT_APP_ATTRIBUTE, FOLDKIT_FLAGS_ATTRIBUTE, } from '../../hydrationMarker.js';
|
|
4
|
+
import { parseFragmentModes } from './fragment.js';
|
|
4
5
|
import { escapeAttributeValue, escapeText } from './serialize.js';
|
|
5
6
|
import { __assertNoDeclarativeShadowRoot, __assertNoDocumentStructureEscape, __assertNoLiveBaseElement, } from './server.js';
|
|
6
7
|
const DEFAULT_CONTAINER_ID = 'root';
|
|
@@ -236,10 +237,7 @@ const shapesAround = (parent, child) => {
|
|
|
236
237
|
}
|
|
237
238
|
return { shapes, index };
|
|
238
239
|
};
|
|
239
|
-
const assertInjectionIsFaithful = (page,
|
|
240
|
-
const parsedTemplate = parse(template, {
|
|
241
|
-
scriptingEnabled: isScriptingEnabled,
|
|
242
|
-
});
|
|
240
|
+
const assertInjectionIsFaithful = (page, parsedTemplate, renderedHtml, containerId, isScriptingEnabled) => {
|
|
243
241
|
const container = firstMatching(parsedTemplate, element => isContainerPlaceholder(element, containerId));
|
|
244
242
|
const containerParent = container === undefined ? undefined : parentOf(container);
|
|
245
243
|
if (container === undefined || containerParent === undefined) {
|
|
@@ -362,11 +360,7 @@ const assertRenderedSourceIsPreserved = (renderedHtml, parsed) => {
|
|
|
362
360
|
};
|
|
363
361
|
// The runtime id the rendered markup stamps on its root, or `undefined` when it
|
|
364
362
|
// carries no stamp (a render that nothing will hydrate).
|
|
365
|
-
const runtimeIdInMode = (renderedHtml,
|
|
366
|
-
const parsed = parseFragment(RENDERED_FRAGMENT_CONTEXT, renderedHtml, {
|
|
367
|
-
scriptingEnabled: isScriptingEnabled,
|
|
368
|
-
sourceCodeLocationInfo: true,
|
|
369
|
-
});
|
|
363
|
+
const runtimeIdInMode = (renderedHtml, parsed) => {
|
|
370
364
|
assertRenderedSourceIsPreserved(renderedHtml, parsed);
|
|
371
365
|
const applicationMarkers = collectMatchingIncludingTemplateContent(parsed, element => attributeValue(element, FOLDKIT_APP_ATTRIBUTE) !== undefined);
|
|
372
366
|
const flagsMarkers = collectMatchingIncludingTemplateContent(parsed, element => attributeValue(element, FOLDKIT_FLAGS_ATTRIBUTE) !== undefined);
|
|
@@ -420,9 +414,9 @@ const runtimeIdInMode = (renderedHtml, isScriptingEnabled) => {
|
|
|
420
414
|
}
|
|
421
415
|
return runtimeId;
|
|
422
416
|
};
|
|
423
|
-
const runtimeIdOf = (renderedHtml) => {
|
|
424
|
-
const enabled = runtimeIdInMode(renderedHtml,
|
|
425
|
-
const disabled = runtimeIdInMode(renderedHtml,
|
|
417
|
+
const runtimeIdOf = (renderedHtml, fragments) => {
|
|
418
|
+
const enabled = runtimeIdInMode(renderedHtml, fragments.scripted);
|
|
419
|
+
const disabled = runtimeIdInMode(renderedHtml, fragments.unscripted);
|
|
426
420
|
if (enabled !== disabled) {
|
|
427
421
|
throw new Error('[foldkit] injectIntoTemplate received rendered markup whose root and ' +
|
|
428
422
|
'Flags ownership changes when scripting is disabled.');
|
|
@@ -501,7 +495,11 @@ export const injectIntoTemplate = (template, rendered, options) => {
|
|
|
501
495
|
// Distinct ids are not a licence to hydrate two applications on one page.
|
|
502
496
|
// Each page-owning application rewrites the document's metadata and installs
|
|
503
497
|
// its own navigation listeners, which no id divides between them.
|
|
504
|
-
const
|
|
498
|
+
const { html: renderedHtml } = rendered;
|
|
499
|
+
const fragments = parseFragmentModes(RENDERED_FRAGMENT_CONTEXT, renderedHtml, {
|
|
500
|
+
sourceCodeLocationInfo: true,
|
|
501
|
+
});
|
|
502
|
+
const renderedRuntimeId = runtimeIdOf(renderedHtml, fragments);
|
|
505
503
|
if (renderedRuntimeId !== undefined) {
|
|
506
504
|
const existing = collectMatching(document, element => attributeValue(element, FOLDKIT_APP_ATTRIBUTE) === renderedRuntimeId);
|
|
507
505
|
if (existing.length > 0) {
|
|
@@ -551,15 +549,15 @@ export const injectIntoTemplate = (template, rendered, options) => {
|
|
|
551
549
|
const mutations = [];
|
|
552
550
|
const container = containers[0];
|
|
553
551
|
assertNeutralInsertionContext(container, containerId);
|
|
554
|
-
__assertNoDeclarativeShadowRoot(
|
|
555
|
-
__assertNoDocumentStructureEscape(
|
|
556
|
-
__assertNoLiveBaseElement(
|
|
552
|
+
__assertNoDeclarativeShadowRoot(fragments);
|
|
553
|
+
__assertNoDocumentStructureEscape(renderedHtml);
|
|
554
|
+
__assertNoLiveBaseElement(fragments);
|
|
557
555
|
const containerLocation = container.sourceCodeLocation;
|
|
558
556
|
if (containerLocation != null) {
|
|
559
557
|
mutations.push({
|
|
560
558
|
start: containerLocation.startOffset,
|
|
561
559
|
end: containerLocation.endOffset,
|
|
562
|
-
replacement:
|
|
560
|
+
replacement: renderedHtml,
|
|
563
561
|
});
|
|
564
562
|
}
|
|
565
563
|
const title = titles[0];
|
|
@@ -623,7 +621,10 @@ export const injectIntoTemplate = (template, rendered, options) => {
|
|
|
623
621
|
// document the same way, and markup the parser drops is lost with no
|
|
624
622
|
// hydration to rebuild it.
|
|
625
623
|
for (const isScriptingEnabled of [true, false]) {
|
|
626
|
-
|
|
624
|
+
const parsedTemplate = isScriptingEnabled
|
|
625
|
+
? document
|
|
626
|
+
: parse(template, { scriptingEnabled: false });
|
|
627
|
+
assertInjectionIsFaithful(page, parsedTemplate, renderedHtml, containerId, isScriptingEnabled);
|
|
627
628
|
}
|
|
628
629
|
return page;
|
|
629
630
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrationHandoff.d.ts","sourceRoot":"","sources":["../../src/runtime/hydrationHandoff.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"hydrationHandoff.d.ts","sourceRoot":"","sources":["../../src/runtime/hydrationHandoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,MAAM,EAAE,MAAM,EAAa,MAAM,EAAQ,MAAM,QAAQ,CAAA;AAQ7E;wCACwC;AACxC,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;AAK1C,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,WAAW,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAA;IAC9C,eAAe,EAAE,OAAO,CAAA;CACzB,CAAC,CAAA;AA0GF,eAAO,MAAM,SAAS,SACd,WAAW,WACR,OAAO,aACL,MAAM,KAChB,KAAK,GAAG,SAwBV,CAAA;AAmJD,eAAO,MAAM,kBAAkB,kBAAmB,QAAQ,KAAG,IAO5D,CAAA;AAOD,eAAO,MAAM,uBAAuB,kBAAmB,QAAQ,KAAG,OAItD,CAAA;AAEZ,eAAO,MAAM,qBAAqB,cACrB,WAAW,GAAG,IAAI,mBACZ,OAAO,KACvB,eAAe,GAAG,SAyDpB,CAAA;AAED;;;oBAGoB;AACpB,MAAM,MAAM,wBAAwB,CAAC,KAAK,IAAI,QAAQ,CAAC;IACrD,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC9C,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;CACnC,CAAC,CAAA;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,EAAE,SAAS,2IAWrD,QAAQ,CAAC;IACV,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,EAAE,eAAe,GAAG,SAAS,CAAA;IACtC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,SAAS,CAAA;IAC7D,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAA;IACtE,eAAe,EAAE,OAAO,CAAA;IACxB,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACtD,cAAc,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,WAAW,CAAA;IACtB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,gBAAgB,EAAE,CAAC,CAAC,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KACvC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;CACtB,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAuK9C,CAAA"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { Array, Effect, Option, Predicate, Schema, pipe } from 'effect';
|
|
1
|
+
import { Array, Data, Effect, Option, Predicate, Schema, pipe } from 'effect';
|
|
2
2
|
import { HYDRATION_BUILD_ATTRIBUTE } from '../buildToken.js';
|
|
3
3
|
import { FOLDKIT_APP_ATTRIBUTE, FOLDKIT_FLAGS_ATTRIBUTE, } from '../hydrationMarker.js';
|
|
4
|
+
class FlagsPayloadDecodeFailed extends Data.TaggedError('FlagsPayloadDecodeFailed') {
|
|
5
|
+
}
|
|
4
6
|
const hydrationForRoot = (root, isFlagsRequired) => {
|
|
5
7
|
const runtimeId = root.getAttribute(FOLDKIT_APP_ATTRIBUTE) ?? '';
|
|
6
8
|
const flagsScripts = pipe(Array.fromIterable(document.querySelectorAll(`script[${FOLDKIT_FLAGS_ATTRIBUTE}]`)), Array.filter(script => script.getAttribute(FOLDKIT_FLAGS_ATTRIBUTE) === runtimeId));
|
|
@@ -334,7 +336,7 @@ export const resolveHydrationHandoff = ({ bootMode, hydration, bootFlags, config
|
|
|
334
336
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
335
337
|
Schema.toCodecJson(FlagsCodec), Schema.decodeUnknownSync, decode => decode(parsedPayload));
|
|
336
338
|
},
|
|
337
|
-
catch: cause => cause,
|
|
339
|
+
catch: cause => new FlagsPayloadDecodeFailed({ cause }),
|
|
338
340
|
}).pipe(Effect.catch(cause => refuseHydration(root, '[foldkit] Runtime.hydrate could not decode the server ' +
|
|
339
341
|
`Flags payload for application "${runtimeId}". The HTML ` +
|
|
340
342
|
'and client bundle must use the same Flags Schema.', cause)));
|
package/dist/runtime/runtime.js
CHANGED
|
@@ -374,7 +374,7 @@ export const makeRuntime = ({ ports, kind, Model, Flags: FlagsCodec, configuredF
|
|
|
374
374
|
// callbacks, so this fiber's only remaining job is keeping the
|
|
375
375
|
// runtime scope open until interruption (an embedded app's dispose)
|
|
376
376
|
// or the document goes away.
|
|
377
|
-
yield* Effect.never;
|
|
377
|
+
return yield* Effect.never;
|
|
378
378
|
})).pipe(Effect.provideService(RenderCommit, commitNotifier.service), Effect.provideService(DialogRuntime, {
|
|
379
379
|
register: id => {
|
|
380
380
|
dialogIds.add(id);
|