tungsten 0.3.1 → 0.3.3
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/.build-complete +1 -0
- package/dist/Components.d.ts +2 -1
- package/dist/Components.d.ts.map +1 -1
- package/dist/Components.js +10 -1
- package/dist/DomRegion.js +1 -1
- package/dist/Framework.d.ts +2 -0
- package/dist/Framework.d.ts.map +1 -1
- package/dist/Framework.js +68 -57
- package/dist/FrameworkConfig.d.ts +6 -0
- package/dist/FrameworkConfig.d.ts.map +1 -1
- package/dist/FunctionComponentStandIn.d.ts +2 -0
- package/dist/FunctionComponentStandIn.d.ts.map +1 -1
- package/dist/FunctionComponentStandIn.js +10 -1
- package/dist/Instance/Instance.d.ts.map +1 -1
- package/dist/Instance/Instance.js +18 -1
- package/dist/Instance/InstanceConfig.d.ts +1 -0
- package/dist/Instance/InstanceConfig.d.ts.map +1 -1
- package/dist/PopMessage.type.d.ts +6 -0
- package/dist/PopMessage.type.d.ts.map +1 -0
- package/dist/PopMessage.type.js +1 -0
- package/dist/Servers/DevServer.d.ts +4 -0
- package/dist/Servers/DevServer.d.ts.map +1 -1
- package/dist/Servers/DevServer.js +116 -13
- package/dist/Servers/MatchedRouteInfo.d.ts +1 -1
- package/dist/Servers/MatchedRouteInfo.d.ts.map +1 -1
- package/dist/Servers/ProdServer.d.ts +1 -0
- package/dist/Servers/ProdServer.d.ts.map +1 -1
- package/dist/Servers/ProdServer.js +79 -5
- package/dist/Servers/devErrorPageAutoRetry.d.ts +4 -0
- package/dist/Servers/devErrorPageAutoRetry.d.ts.map +1 -0
- package/dist/Servers/devErrorPageAutoRetry.js +26 -0
- package/dist/Servers/hono/DevServerHono.js +25 -29
- package/dist/Servers/hono/ProdServerHono.js +49 -142
- package/dist/Servers/hono/TungstenServerHono.d.ts +1 -1
- package/dist/Servers/hono/TungstenServerHono.d.ts.map +1 -1
- package/dist/Servers/hono/TungstenServerHono.js +12 -29
- package/dist/Servers/routing.d.ts.map +1 -1
- package/dist/Servers/routing.js +10 -6
- package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts +0 -3
- package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts.map +1 -1
- package/dist/Servers/tungstenCorePrivateEnvSchema.js +3 -3
- package/dist/Servers/tungstenCorePublicEnvSchema.d.ts +8 -0
- package/dist/Servers/tungstenCorePublicEnvSchema.d.ts.map +1 -0
- package/dist/Servers/tungstenCorePublicEnvSchema.js +14 -0
- package/dist/Store/InternalStoreSchema.d.ts +2 -0
- package/dist/Store/InternalStoreSchema.d.ts.map +1 -1
- package/dist/Store/InternalStoreSchema.js +1 -0
- package/dist/api/Request.d.ts +1 -1
- package/dist/api/Request.d.ts.map +1 -1
- package/dist/api/Response.d.ts +1 -1
- package/dist/api/Response.d.ts.map +1 -1
- package/dist/api/getExport.d.ts.map +1 -1
- package/dist/api/getExport.js +2 -1
- package/dist/babelPlugins/BabelAddDevCacheBust.d.ts +11 -0
- package/dist/babelPlugins/BabelAddDevCacheBust.d.ts.map +1 -0
- package/dist/babelPlugins/BabelAddDevCacheBust.js +68 -0
- package/dist/babelPlugins/BabelTypes.d.ts +2 -2
- package/dist/babelPlugins/BabelTypes.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTypes.js +0 -1
- package/dist/bin/commands/build.d.ts.map +1 -1
- package/dist/bin/commands/build.js +3 -0
- package/dist/bin/commands/dev.d.ts.map +1 -1
- package/dist/bin/commands/dev.js +16 -3
- package/dist/bin/commands/devmon.d.ts +2 -0
- package/dist/bin/commands/devmon.d.ts.map +1 -0
- package/dist/bin/commands/devmon.js +66 -0
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +6 -0
- package/dist/booleanAttributeValue.d.ts +21 -0
- package/dist/booleanAttributeValue.d.ts.map +1 -0
- package/dist/booleanAttributeValue.js +23 -0
- package/dist/build/compileJavascript.js +1 -1
- package/dist/build/compileUserApp.d.ts +2 -1
- package/dist/build/compileUserApp.d.ts.map +1 -1
- package/dist/build/compileUserApp.js +10 -9
- package/dist/build/createInstanceConfigFile.js +1 -1
- package/dist/build/makeBabelUserDevConfig.d.ts.map +1 -1
- package/dist/build/makeBabelUserDevConfig.js +6 -1
- package/dist/compat/types.d.ts +1 -1
- package/dist/compat/types.d.ts.map +1 -1
- package/dist/components/PopMessages.d.ts +12 -0
- package/dist/components/PopMessages.d.ts.map +1 -0
- package/dist/components/PopMessages.js +45 -0
- package/dist/defaultConfig.d.ts +3 -0
- package/dist/defaultConfig.d.ts.map +1 -1
- package/dist/defaultConfig.js +4 -1
- package/dist/env/Interfaces.d.ts +2 -1
- package/dist/env/Interfaces.d.ts.map +1 -1
- package/dist/env/getEnvSchemas.d.ts +1 -1
- package/dist/env/getEnvSchemas.d.ts.map +1 -1
- package/dist/env/getEnvSchemas.js +2 -1
- package/dist/env/publicEnv.d.ts.map +1 -1
- package/dist/env/publicEnv.js +4 -1
- package/dist/frameworkConfigSchema.d.ts +4 -0
- package/dist/frameworkConfigSchema.d.ts.map +1 -1
- package/dist/frameworkConfigSchema.js +2 -1
- package/dist/getComponent.d.ts.map +1 -1
- package/dist/getComponent.js +2 -1
- package/dist/getRoutes.d.ts.map +1 -1
- package/dist/getRoutes.js +2 -1
- package/dist/hmr/applyHmrModule.d.ts +11 -0
- package/dist/hmr/applyHmrModule.d.ts.map +1 -0
- package/dist/hmr/applyHmrModule.js +78 -0
- package/dist/hmr/componentIdentity.d.ts +9 -0
- package/dist/hmr/componentIdentity.d.ts.map +1 -0
- package/dist/hmr/componentIdentity.js +17 -0
- package/dist/hmr/instanceRegistry.d.ts +4 -0
- package/dist/hmr/instanceRegistry.d.ts.map +1 -0
- package/dist/hmr/instanceRegistry.js +6 -0
- package/dist/hmr/liveReloadHub.d.ts +10 -0
- package/dist/hmr/liveReloadHub.d.ts.map +1 -0
- package/dist/{dev → hmr}/liveReloadHub.js +8 -2
- package/dist/hmr/refreshStylesheets.d.ts +2 -0
- package/dist/hmr/refreshStylesheets.d.ts.map +1 -0
- package/dist/hmr/refreshStylesheets.js +26 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useInstance.d.ts +3 -0
- package/dist/hooks/useInstance.d.ts.map +1 -0
- package/dist/hooks/useInstance.js +4 -0
- package/dist/hydrate/hydrate.d.ts +10 -0
- package/dist/hydrate/hydrate.d.ts.map +1 -1
- package/dist/hydrate/hydrate.js +81 -19
- package/dist/hydrate/reconcileHydratedAttributes.d.ts.map +1 -1
- package/dist/hydrate/reconcileHydratedAttributes.js +14 -5
- package/dist/hydrate/renderHydrationMismatchBanner.d.ts +7 -0
- package/dist/hydrate/renderHydrationMismatchBanner.d.ts.map +1 -0
- package/dist/hydrate/renderHydrationMismatchBanner.js +69 -0
- package/dist/importDevModuleWithRetry.d.ts +3 -0
- package/dist/importDevModuleWithRetry.d.ts.map +1 -0
- package/dist/importDevModuleWithRetry.js +46 -0
- package/dist/indexInner.d.ts +8 -0
- package/dist/indexInner.d.ts.map +1 -1
- package/dist/indexInner.js +7 -1
- package/dist/makeInstanceConfigFromFrameworkConfig.d.ts.map +1 -1
- package/dist/makeInstanceConfigFromFrameworkConfig.js +2 -1
- package/dist/pop.d.ts +10 -0
- package/dist/pop.d.ts.map +1 -0
- package/dist/pop.js +49 -0
- package/dist/rawHtml/filterContentNode.d.ts +20 -0
- package/dist/rawHtml/filterContentNode.d.ts.map +1 -0
- package/dist/rawHtml/filterContentNode.js +96 -0
- package/dist/rawHtml/parseHtml.d.ts +14 -0
- package/dist/rawHtml/parseHtml.d.ts.map +1 -1
- package/dist/rawHtml/parseHtml.js +4 -4
- package/dist/rawHtml/sanitizeHtml.d.ts +17 -0
- package/dist/rawHtml/sanitizeHtml.d.ts.map +1 -0
- package/dist/rawHtml/sanitizeHtml.js +19 -0
- package/dist/render/HeadData.d.ts +2 -0
- package/dist/render/HeadData.d.ts.map +1 -1
- package/dist/render/contentNodeToHtml.d.ts +18 -0
- package/dist/render/contentNodeToHtml.d.ts.map +1 -0
- package/dist/render/contentNodeToHtml.js +66 -0
- package/dist/render/contentToHtml.d.ts.map +1 -1
- package/dist/render/contentToHtml.js +3 -1
- package/dist/render/processHead.d.ts.map +1 -1
- package/dist/render/processHead.js +53 -6
- package/dist/render/renderingTreeToHtml.d.ts.map +1 -1
- package/dist/render/renderingTreeToHtml.js +8 -1
- package/dist/routing/ErrorRouteType.d.ts +6 -0
- package/dist/routing/ErrorRouteType.d.ts.map +1 -0
- package/dist/routing/ErrorRouteType.js +1 -0
- package/dist/routing/RouteTypes.d.ts +2 -1
- package/dist/routing/RouteTypes.d.ts.map +1 -1
- package/dist/routing/Routes.d.ts +5 -0
- package/dist/routing/Routes.d.ts.map +1 -1
- package/dist/routing/TungstenErrorInfo.d.ts +6 -0
- package/dist/routing/TungstenErrorInfo.d.ts.map +1 -0
- package/dist/routing/TungstenErrorInfo.js +6 -0
- package/dist/style/styleContentSxy.js +21 -0
- package/dist/testing/hydrateTestApp.d.ts +38 -0
- package/dist/testing/hydrateTestApp.d.ts.map +1 -0
- package/dist/testing/hydrateTestApp.js +242 -0
- package/dist/testing/index.d.ts +4 -3
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +16 -2
- package/dist/timeProfiler.d.ts +6 -0
- package/dist/timeProfiler.d.ts.map +1 -0
- package/dist/timeProfiler.js +31 -0
- package/dist/update/integrateUpdateVdom.d.ts +16 -1
- package/dist/update/integrateUpdateVdom.d.ts.map +1 -1
- package/dist/update/integrateUpdateVdom.js +116 -7
- package/dist/warnOnFrameworkChange.d.ts +2 -0
- package/dist/warnOnFrameworkChange.d.ts.map +1 -0
- package/dist/warnOnFrameworkChange.js +27 -0
- package/package.json +18 -16
- package/dist/Instance/gotoRedirect.sxyt.d.ts +0 -2
- package/dist/Instance/gotoRedirect.sxyt.d.ts.map +0 -1
- package/dist/Instance/gotoRedirect.sxyt.js +0 -148
- package/dist/Instance/runTrackedWork.sxyt.d.ts +0 -2
- package/dist/Instance/runTrackedWork.sxyt.d.ts.map +0 -1
- package/dist/Instance/runTrackedWork.sxyt.js +0 -35
- package/dist/_client/cjsHelpers.sxyt.d.ts +0 -2
- package/dist/_client/cjsHelpers.sxyt.d.ts.map +0 -1
- package/dist/_client/cjsHelpers.sxyt.js +0 -45
- package/dist/auth/passwordHashing.sxyt.d.ts +0 -2
- package/dist/auth/passwordHashing.sxyt.d.ts.map +0 -1
- package/dist/auth/passwordHashing.sxyt.js +0 -46
- package/dist/auth/ref/checkPasswordResetToken.sxyt.d.ts +0 -2
- package/dist/auth/ref/checkPasswordResetToken.sxyt.d.ts.map +0 -1
- package/dist/auth/ref/checkPasswordResetToken.sxyt.js +0 -40
- package/dist/auth/ref/createPasswordResetToken.sxyt.d.ts +0 -2
- package/dist/auth/ref/createPasswordResetToken.sxyt.d.ts.map +0 -1
- package/dist/auth/ref/createPasswordResetToken.sxyt.js +0 -10
- package/dist/babelPlugins/fixImportsInSassErrorMessage.sxyt.d.ts +0 -2
- package/dist/babelPlugins/fixImportsInSassErrorMessage.sxyt.d.ts.map +0 -1
- package/dist/babelPlugins/fixImportsInSassErrorMessage.sxyt.js +0 -108
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.d.ts +0 -2
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.d.ts.map +0 -1
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.js +0 -104
- package/dist/bin/commands/compile.sxyt.d.ts +0 -2
- package/dist/bin/commands/compile.sxyt.d.ts.map +0 -1
- package/dist/bin/commands/compile.sxyt.js +0 -255
- package/dist/build/modifySassImports.sxyt.d.ts +0 -2
- package/dist/build/modifySassImports.sxyt.d.ts.map +0 -1
- package/dist/build/modifySassImports.sxyt.js +0 -55
- package/dist/build/sassImportParser.sxyt.d.ts +0 -2
- package/dist/build/sassImportParser.sxyt.d.ts.map +0 -1
- package/dist/build/sassImportParser.sxyt.js +0 -110
- package/dist/build/scssImportParserChatgpt.sxyt.d.ts +0 -2
- package/dist/build/scssImportParserChatgpt.sxyt.d.ts.map +0 -1
- package/dist/build/scssImportParserChatgpt.sxyt.js +0 -120
- package/dist/clone.sxyt.d.ts +0 -2
- package/dist/clone.sxyt.d.ts.map +0 -1
- package/dist/clone.sxyt.js +0 -24
- package/dist/componentProxyHandlers.sxyt.d.ts +0 -2
- package/dist/componentProxyHandlers.sxyt.d.ts.map +0 -1
- package/dist/componentProxyHandlers.sxyt.js +0 -130
- package/dist/components/RawHtml.sxyt.d.ts +0 -2
- package/dist/components/RawHtml.sxyt.d.ts.map +0 -1
- package/dist/components/RawHtml.sxyt.js +0 -104
- package/dist/components/bindable/BindableSelect.sxyt.d.ts +0 -2
- package/dist/components/bindable/BindableSelect.sxyt.d.ts.map +0 -1
- package/dist/components/bindable/BindableSelect.sxyt.js +0 -186
- package/dist/dev/liveReloadHub.d.ts +0 -6
- package/dist/dev/liveReloadHub.d.ts.map +0 -1
- package/dist/env/injectEnv.sxyt.d.ts +0 -2
- package/dist/env/injectEnv.sxyt.d.ts.map +0 -1
- package/dist/env/injectEnv.sxyt.js +0 -20
- package/dist/env/parseEnv.sxyt.d.ts +0 -2
- package/dist/env/parseEnv.sxyt.d.ts.map +0 -1
- package/dist/env/parseEnv.sxyt.js +0 -11
- package/dist/findProjectDir.sxyt.d.ts +0 -2
- package/dist/findProjectDir.sxyt.d.ts.map +0 -1
- package/dist/findProjectDir.sxyt.js +0 -82
- package/dist/hydrate/reconcileHydratedAttributes.sxyt.d.ts +0 -2
- package/dist/hydrate/reconcileHydratedAttributes.sxyt.d.ts.map +0 -1
- package/dist/hydrate/reconcileHydratedAttributes.sxyt.js +0 -173
- package/dist/innerHtmlFromProps.sxyt.d.ts +0 -2
- package/dist/innerHtmlFromProps.sxyt.d.ts.map +0 -1
- package/dist/innerHtmlFromProps.sxyt.js +0 -99
- package/dist/postcssPlugins/parseSelectors.sxyt.d.ts +0 -2
- package/dist/postcssPlugins/parseSelectors.sxyt.d.ts.map +0 -1
- package/dist/postcssPlugins/parseSelectors.sxyt.js +0 -62
- package/dist/postcssPlugins/parseSelectorsRich.sxyt.d.ts +0 -2
- package/dist/postcssPlugins/parseSelectorsRich.sxyt.d.ts.map +0 -1
- package/dist/postcssPlugins/parseSelectorsRich.sxyt.js +0 -155
- package/dist/rawHtml/parseHtml.sxyt.d.ts +0 -2
- package/dist/rawHtml/parseHtml.sxyt.d.ts.map +0 -1
- package/dist/rawHtml/parseHtml.sxyt.js +0 -239
- package/dist/render/getFunctionBodyAsString.sxyt.d.ts +0 -2
- package/dist/render/getFunctionBodyAsString.sxyt.d.ts.map +0 -1
- package/dist/render/getFunctionBodyAsString.sxyt.js +0 -37
- package/dist/render/processProps.sxyt.d.ts +0 -2
- package/dist/render/processProps.sxyt.d.ts.map +0 -1
- package/dist/render/processProps.sxyt.js +0 -90
- package/dist/routing/compareRequestToRegex.sxyt.d.ts +0 -2
- package/dist/routing/compareRequestToRegex.sxyt.d.ts.map +0 -1
- package/dist/routing/compareRequestToRegex.sxyt.js +0 -65
- package/dist/routing/getPathPriority.sxyt.d.ts +0 -2
- package/dist/routing/getPathPriority.sxyt.d.ts.map +0 -1
- package/dist/routing/getPathPriority.sxyt.js +0 -24
- package/dist/routing/matchPath.sxyt.d.ts +0 -2
- package/dist/routing/matchPath.sxyt.d.ts.map +0 -1
- package/dist/routing/matchPath.sxyt.js +0 -41
- package/dist/routing/patternToRegex.sxyt.d.ts +0 -2
- package/dist/routing/patternToRegex.sxyt.d.ts.map +0 -1
- package/dist/routing/patternToRegex.sxyt.js +0 -69
- package/dist/routing/splitRequest.sxyt.d.ts +0 -2
- package/dist/routing/splitRequest.sxyt.d.ts.map +0 -1
- package/dist/routing/splitRequest.sxyt.js +0 -47
- package/dist/style/jssToCss.sxyt.d.ts +0 -2
- package/dist/style/jssToCss.sxyt.d.ts.map +0 -1
- package/dist/style/jssToCss.sxyt.js +0 -17
- package/dist/testing/createTestApp.sxyt.d.ts +0 -2
- package/dist/testing/createTestApp.sxyt.d.ts.map +0 -1
- package/dist/testing/createTestApp.sxyt.js +0 -470
- package/dist/testing/ensureTestEnvLoaded.sxyt.d.ts +0 -2
- package/dist/testing/ensureTestEnvLoaded.sxyt.d.ts.map +0 -1
- package/dist/testing/ensureTestEnvLoaded.sxyt.js +0 -20
|
@@ -22,7 +22,9 @@ export async function contentToHtml(compilationInfo, clientImportAliases, conten
|
|
|
22
22
|
compilationLocation: compilationInfo.buildCodeLocation,
|
|
23
23
|
dev,
|
|
24
24
|
tungstenPublicEnv,
|
|
25
|
-
siteBasePath: siteBasePathOverride
|
|
25
|
+
siteBasePath: siteBasePathOverride,
|
|
26
|
+
hmr: config.hmr,
|
|
27
|
+
csr: config.csr
|
|
26
28
|
};
|
|
27
29
|
//console.log('rendering tree', inspect(tree, { depth: 99 } ))
|
|
28
30
|
let html = await renderingNodeToHtml(tree, false, headData, null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processHead.d.ts","sourceRoot":"","sources":["../../src/render/processHead.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAK7C,OAAO,EAAE,oBAAoB,EAAqB,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"processHead.d.ts","sourceRoot":"","sources":["../../src/render/processHead.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAK7C,OAAO,EAAE,oBAAoB,EAAqB,MAAM,qBAAqB,CAAA;AAS7E,wBAAgB,WAAW,CACvB,QAAQ,EAAE,oBAAoB,EAC9B,QAAQ,EAAE,QAAQ,QA6MrB"}
|
|
@@ -3,6 +3,8 @@ import { clientFolder, componentCssFolder, componentCssFile } from "../settings.
|
|
|
3
3
|
import { addImportMap } from "./addImportMap.js";
|
|
4
4
|
import { $props, $type } from "../contentNodeSymbols.js";
|
|
5
5
|
import { windowGlobalEnvStatement } from 'tungsten/env/windowGlobalEnvStatement.js';
|
|
6
|
+
import { frameworkDestLocation } from "../build/frameworkDestLocation.js";
|
|
7
|
+
import { devErrorPageClearRetryScript } from "../Servers/devErrorPageAutoRetry.js";
|
|
6
8
|
// process the tree returned by the root component
|
|
7
9
|
// doing things like ensuring there is are html and head elements,
|
|
8
10
|
// and adding necessary style and script tags
|
|
@@ -12,7 +14,8 @@ export function processHead(headNode, headData) {
|
|
|
12
14
|
importAliases,
|
|
13
15
|
clientImportAliases,
|
|
14
16
|
dev,
|
|
15
|
-
siteBasePath
|
|
17
|
+
siteBasePath,
|
|
18
|
+
hmr
|
|
16
19
|
} = headData;
|
|
17
20
|
//console.log('processing head. dev is', dev)
|
|
18
21
|
if (headNode[$props].children === undefined) headNode[$props].children = [];else if (!Array.isArray(headNode[$props].children)) headNode[$props].children = [headNode[$props].children];
|
|
@@ -59,16 +62,60 @@ export function processHead(headNode, headData) {
|
|
|
59
62
|
};
|
|
60
63
|
cjsHelpersScriptNode[$props].type = 'module';
|
|
61
64
|
headNode[$props].children.unshift(cjsHelpersScriptNode);
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
+
// A successful render means whatever the error page's auto-retry script (see
|
|
66
|
+
// devErrorPageAutoRetry.ts) may have been counting is over - clear it so a later,
|
|
67
|
+
// unrelated transient error gets its own full retry budget instead of inheriting a
|
|
68
|
+
// stale count.
|
|
69
|
+
const clearErrorRetryScriptNode = {
|
|
65
70
|
[$type]: 'script',
|
|
66
71
|
[$props]: {
|
|
67
72
|
'data--t-internal': undefined,
|
|
68
|
-
children:
|
|
73
|
+
children: devErrorPageClearRetryScript
|
|
69
74
|
}
|
|
70
75
|
};
|
|
71
|
-
headNode[$props].children.unshift(
|
|
76
|
+
headNode[$props].children.unshift(clearErrorRetryScriptNode);
|
|
77
|
+
// Auto-reload / HMR. This has to stay a raw inline script rather than a real imported
|
|
78
|
+
// module: it fetches whichever file just recompiled via a computed, cache-busted
|
|
79
|
+
// import() call, and any dynamic import() with a non-literal argument anywhere in the
|
|
80
|
+
// framework's traced dependency graph makes the package-copying step that serves
|
|
81
|
+
// framework code to the browser throw (it requires every import specifier to be
|
|
82
|
+
// statically known so it can be rewritten/copied). Keeping this logic as untraced text
|
|
83
|
+
// sidesteps that. applyHmrModule.js itself has no dynamic imports, so it's safely
|
|
84
|
+
// reachable via a normal static import elsewhere (see hydrate.tsx) and gets copied
|
|
85
|
+
// there, then loaded here by computed URL. See tungsten/docs/hmr.md.
|
|
86
|
+
// Tier 1 (hmr: 'reload', or nothing left for Tier 2 to do): always full-reload. A
|
|
87
|
+
// simple, independent branch from Tier 2's logic - restored as an explicit config value
|
|
88
|
+
// so it's available as a one-line escape hatch if Tier 2 itself is misbehaving.
|
|
89
|
+
// The server sends its bootId as the first event on every connection (see
|
|
90
|
+
// handleLiveReloadStream). If sessionStorage already holds a different one, this
|
|
91
|
+
// connection is a reconnect to a process that restarted since the page loaded (e.g. via
|
|
92
|
+
// tungsten devmon on a framework rebuild) - EventSource retries silently on its own, so
|
|
93
|
+
// this is the only reliable signal that the page is now stale and needs reloading.
|
|
94
|
+
const bootIdReloadSnippet = `es.addEventListener('boot',function(ev){` + `var bootId=JSON.parse(ev.data).bootId;` + `var key='__tungsten_boot_id__';` + `var prev=sessionStorage.getItem(key);` + `sessionStorage.setItem(key,bootId);` + `if(prev!==null&&prev!==bootId){location.reload()}` + `});`;
|
|
95
|
+
const tier1OnlyScript = `(function(){` + `var es=new EventSource('${siteBasePath}/__tungsten_live_reload__');` + bootIdReloadSnippet + `es.addEventListener('css',function(){location.reload()});` + `es.addEventListener('js',function(){location.reload()});` + `})();`;
|
|
96
|
+
// Tier 2: attempt an in-place component/CSS hot-swap before falling back to a full
|
|
97
|
+
// reload. See tungsten/docs/hmr.md.
|
|
98
|
+
const tier2Script = `(function(){` + `var es=new EventSource('${siteBasePath}/__tungsten_live_reload__');` + `function fullReload(reason){console.info('[tungsten-hmr] full reload:',reason);location.reload()}` + `es.addEventListener('boot',function(ev){` + `var bootId=JSON.parse(ev.data).bootId;` + `var key='__tungsten_boot_id__';` + `var prev=sessionStorage.getItem(key);` + `sessionStorage.setItem(key,bootId);` + `if(prev!==null&&prev!==bootId){fullReload('dev server restarted')}` + `});` + `function loadHmr(){return import('${frameworkDestLocation}/hmr/applyHmrModule.js')}`
|
|
99
|
+
// CSS has no state to preserve, so re-applying it is always safe: refreshStylesheets()
|
|
100
|
+
// inserts the new link and only removes the old one once it's loaded, so there's no
|
|
101
|
+
// gap where nothing is applied (a plain href swap can produce a visible flash).
|
|
102
|
+
+ `es.addEventListener('css',function(){` + `console.info('[tungsten-hmr] css change, refreshing stylesheets');` + `loadHmr().then(function(hmr){return Promise.all(hmr.refreshStylesheets())})` + `.catch(function(e){console.error('[tungsten-hmr] stylesheet refresh failed',e)});` + `});` + `es.addEventListener('js',function(ev){` + `var payload;` + `try{payload=JSON.parse(ev.data)}catch(e){fullReload('bad payload');return}` + `var files=(payload&&payload.files)||[];` + `if(files.length===0){fullReload('no files in payload');return}` + `console.info('[tungsten-hmr] fetching',files);` + `loadHmr().then(function(hmr){`
|
|
103
|
+
// a component's own inline style block piggybacks on this same JS pipeline (it
|
|
104
|
+
// lives in the .tsx/.jsx source, not a separate .css file), so refresh stylesheets
|
|
105
|
+
// here too rather than only on a dedicated 'css' event - independently of the
|
|
106
|
+
// component swap below, so a stylesheet load error doesn't force a full reload.
|
|
107
|
+
+ `Promise.all(hmr.refreshStylesheets())` + `.catch(function(e){console.error('[tungsten-hmr] stylesheet refresh failed',e)});` + `return Promise.all(files.map(function(f){return import(f+'?t='+Date.now())}))` + `.then(function(modules){` + `return Promise.all(modules.map(function(m,i){return hmr.applyHmrModule(m,files[i])}))` + `})` + `})` + `.then(function(results){` + `console.info('[tungsten-hmr] results',results);` + `if(results.some(function(r){return r&&r.orphaned})){fullReload('a component export was renamed or removed');return}` + `if(!results.some(function(r){return r&&r.matched}))fullReload('no matching live component found')` + `})` + `.catch(function(e){console.error('[tungsten-hmr] swap failed',e);fullReload('error during swap')});` + `});` + `})();`;
|
|
108
|
+
// hmr === false: no live-reload script at all (auto-refresh fully disabled).
|
|
109
|
+
if (hmr !== false) {
|
|
110
|
+
const liveReloadScriptNode = {
|
|
111
|
+
[$type]: 'script',
|
|
112
|
+
[$props]: {
|
|
113
|
+
'data--t-internal': undefined,
|
|
114
|
+
children: hmr === true ? tier2Script : tier1OnlyScript
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
headNode[$props].children.unshift(liveReloadScriptNode);
|
|
118
|
+
}
|
|
72
119
|
}
|
|
73
120
|
const {
|
|
74
121
|
content: _,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderingTreeToHtml.d.ts","sourceRoot":"","sources":["../../src/render/renderingTreeToHtml.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"renderingTreeToHtml.d.ts","sourceRoot":"","sources":["../../src/render/renderingTreeToHtml.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAY7C,OAAO,EACH,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAG7C,MAAM,qBAAqB,CAAA;AAU5B,wBAAsB,mBAAmB,CACrC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAC1D,UAAU,EAAE,iBAAiB,GAAG,IAAI,GACrC,OAAO,CAAC,MAAM,CAAC,CA8JjB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { reduce as objectReduce } from 'sxy-lib/objects.js';
|
|
2
|
+
import { booleanAttributeValue } from "../booleanAttributeValue.js";
|
|
2
3
|
import { processProps } from "./processProps.js";
|
|
3
4
|
import { htmlVoidTags } from "./htmlVoidTags.js";
|
|
4
5
|
import { validRenderingChildren } from "../validChildren.js";
|
|
@@ -77,7 +78,9 @@ export async function renderingNodeToHtml(node, noEscape, headData, lastSelect)
|
|
|
77
78
|
const attribs = objectReduce(processProps(attribProps), (string, key, value) => {
|
|
78
79
|
//debug('reducing attr', key, value)
|
|
79
80
|
if (typeof value === 'boolean') {
|
|
80
|
-
|
|
81
|
+
const attrValue = booleanAttributeValue(key, value);
|
|
82
|
+
if (attrValue === null) return string;
|
|
83
|
+
return attrValue === '' ? string + ` ${key}` : string + ` ${key}="${attrValue}"`;
|
|
81
84
|
} else if (value === undefined || value === null) {
|
|
82
85
|
return string;
|
|
83
86
|
} else {
|
|
@@ -86,6 +89,10 @@ export async function renderingNodeToHtml(node, noEscape, headData, lastSelect)
|
|
|
86
89
|
}, '');
|
|
87
90
|
// : ''
|
|
88
91
|
debug('attribs', attribs);
|
|
92
|
+
// CSR: body's own attributes render, its children don't - see FrameworkConfig.ts.
|
|
93
|
+
if (type === 'body' && headData.csr) {
|
|
94
|
+
return html + `<${type}${attribs}></${type}>`;
|
|
95
|
+
}
|
|
89
96
|
if (typeof node[$props].__zoneHtml === 'string') {
|
|
90
97
|
return html + `<${type}${attribs}>${node[$props].__zoneHtml}</${type}>`;
|
|
91
98
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RouteContentFunction } from './RouteContentFunction.js';
|
|
2
|
+
import type { TungstenErrorInfo } from './TungstenErrorInfo.js';
|
|
3
|
+
export type ErrorRouteType = {
|
|
4
|
+
content: RouteContentFunction<object, TungstenErrorInfo>;
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=ErrorRouteType.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorRouteType.d.ts","sourceRoot":"","sources":["../../src/routing/ErrorRouteType.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAM/D,MAAM,MAAM,cAAc,GAAG;IACzB,OAAO,EAAE,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAC3D,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Routes } from './Routes.js';
|
|
2
2
|
export type Path = `/${string}`;
|
|
3
|
-
export type
|
|
3
|
+
export type SpecialRoute = 'default' | '404' | 'error';
|
|
4
|
+
export type RouteKey = Path | SpecialRoute;
|
|
4
5
|
export declare function StringIsValidRouteKey(string: string, routes: Routes): string is RouteKey;
|
|
5
6
|
export declare function StringIsPath(string: string): string is Path;
|
|
6
7
|
export declare function RouteKeyIsPath(path: RouteKey): path is Path;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteTypes.d.ts","sourceRoot":"","sources":["../../src/routing/RouteTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAA;AAC/B,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"RouteTypes.d.ts","sourceRoot":"","sources":["../../src/routing/RouteTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAA;AAC/B,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAA;AACtD,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,YAAY,CAAA;AAE1C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,QAAQ,CAExF;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,IAAI,CAE3D;AACD,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,IAAI,IAAI,CAE3D"}
|
package/dist/routing/Routes.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Path } from './RouteTypes.js';
|
|
2
2
|
import type { RouteType } from './RouteType.js';
|
|
3
|
+
import type { ErrorRouteType } from './ErrorRouteType.js';
|
|
3
4
|
export type MinimumRoutes = {
|
|
4
5
|
default: RouteType<any, any>;
|
|
5
6
|
} | {
|
|
@@ -7,6 +8,8 @@ export type MinimumRoutes = {
|
|
|
7
8
|
};
|
|
8
9
|
export type Routes = {
|
|
9
10
|
[key in Path]: RouteType<any, any>;
|
|
11
|
+
} & {
|
|
12
|
+
'error'?: ErrorRouteType;
|
|
10
13
|
} & ({
|
|
11
14
|
'default': RouteType<any, any>;
|
|
12
15
|
} | {
|
|
@@ -14,6 +17,8 @@ export type Routes = {
|
|
|
14
17
|
});
|
|
15
18
|
export type CustomRoutes<Route extends RouteType<any, any>> = {
|
|
16
19
|
[key in Path]: Route;
|
|
20
|
+
} & {
|
|
21
|
+
error: ErrorRouteType;
|
|
17
22
|
} & ({
|
|
18
23
|
'default': Route;
|
|
19
24
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Routes.d.ts","sourceRoot":"","sources":["../../src/routing/Routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"Routes.d.ts","sourceRoot":"","sources":["../../src/routing/Routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,MAAM,aAAa,GACnB;IAAE,OAAO,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,GAChC;IAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,CAAA;AAEpC,MAAM,MAAM,MAAM,GAAG;KAAG,GAAG,IAAI,IAAI,GAAG,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;CAAE,GACzD;IAAE,OAAO,CAAC,EAAE,cAAc,CAAA;CAAE,GAC5B,CACE;IAAE,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,GAChC;IAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,CACnC,CAAA;AAED,MAAM,MAAM,YAAY,CAAC,KAAK,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI;KAAG,GAAG,IAAI,IAAI,GAAG,KAAK;CAAE,GACpF;IAAE,KAAK,EAAE,cAAc,CAAA;CAAE,GACzB,CACE;IAAE,SAAS,EAAE,KAAK,CAAA;CAAE,GAClB;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CACrB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TungstenErrorInfo.d.ts","sourceRoot":"","sources":["../../src/routing/TungstenErrorInfo.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC5B,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAEvE"}
|
|
@@ -121,6 +121,27 @@ function processItem(element, styles, usage) {
|
|
|
121
121
|
}
|
|
122
122
|
newClassName = newClassName.trim();
|
|
123
123
|
if (newClassName !== '') element[$props].className = newClassName;
|
|
124
|
+
// Any other *ClassName prop (e.g. messageClassName, handed to a child component to apply
|
|
125
|
+
// to one of its own elements) gets the same local-stylesheet lookup applied in place, so a
|
|
126
|
+
// classname threaded down through props can still be scoped against this component's own
|
|
127
|
+
// stylesheet, even though the child's own render tree is outside this walk - see
|
|
128
|
+
// styleContentSxy() above.
|
|
129
|
+
for (const key in element[$props]) {
|
|
130
|
+
if (key === 'className' || !key.endsWith('ClassName')) continue;
|
|
131
|
+
const value = element[$props][key];
|
|
132
|
+
if (value === undefined || value === null) continue;
|
|
133
|
+
if (typeof value !== 'string') {
|
|
134
|
+
throw new TungstenError(`styleContentSxy() error: ${ContentNodeElementIsHtml(element) ? element[$type] : getComponentName(element)}` + ` ${key} prop should be a string. Received ${typeof value}`);
|
|
135
|
+
}
|
|
136
|
+
let newValue = value;
|
|
137
|
+
for (const cn of value.split(' ')) {
|
|
138
|
+
if (cn in styles.classes) {
|
|
139
|
+
newValue += ` ${styles.classes[cn]}`;
|
|
140
|
+
usage?.usedClasses.add(cn);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (newValue !== value) element[$props][key] = newValue;
|
|
144
|
+
}
|
|
124
145
|
debug('element after mods', tagName, element);
|
|
125
146
|
// apply this to both fragment and elements
|
|
126
147
|
if (element[$props].children !== undefined) {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ConstructPackage, TungstenBaseComponent, TungstenComponentPropsBase } from '../Components.jsx';
|
|
2
|
+
import type { TaggedAttributeMismatch } from '../hydrate/renderHydrationMismatchBanner.js';
|
|
3
|
+
import type { TestAppOptions } from './index.js';
|
|
4
|
+
export type HydrateTestAppOptions<Props extends object> = TestAppOptions<Props> & {
|
|
5
|
+
serverProps?: Props;
|
|
6
|
+
csr?: boolean;
|
|
7
|
+
};
|
|
8
|
+
type HydrateTestAppArgs<Props extends object> = object extends Props ? [options?: HydrateTestAppOptions<Props>] : keyof Props extends never ? [options?: HydrateTestAppOptions<Props>] : [options: HydrateTestAppOptions<Props> & {
|
|
9
|
+
props: Props;
|
|
10
|
+
}];
|
|
11
|
+
export type HydrateTestApp<Component extends TungstenBaseComponent> = {
|
|
12
|
+
readonly document: Document;
|
|
13
|
+
readonly container: HTMLElement;
|
|
14
|
+
readonly component: Component;
|
|
15
|
+
readonly html: string;
|
|
16
|
+
readonly mismatches: readonly TaggedAttributeMismatch[];
|
|
17
|
+
resolved(): Promise<void>;
|
|
18
|
+
setProps(props: Component['props']): Promise<void>;
|
|
19
|
+
unmount(): Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The hydration round trip createTestApp() deliberately doesn't cover: render a component to
|
|
23
|
+
* HTML the way a real server would, parse it with a real HTML parser, hydrate a fresh client
|
|
24
|
+
* instance against the result, and hand back the live, hydrated component - still fully usable
|
|
25
|
+
* via setProps()/resolved(), exactly like createTestApp()'s result.
|
|
26
|
+
*
|
|
27
|
+
* By default `props` renders on both sides, so a passing test proves an ordinary page hydrates
|
|
28
|
+
* clean (`mismatches` empty). Pass `serverProps` to diverge the two passes on purpose and assert
|
|
29
|
+
* on the resulting `mismatches` - the case a one-off "does the reconciler still agree with real
|
|
30
|
+
* served pages" script never could, because nothing fed it markup that didn't already match.
|
|
31
|
+
*
|
|
32
|
+
* A structural mismatch (a different tag, a different number of children) is not something
|
|
33
|
+
* reconcileHydratedAttributes() can fix - hydrateRootComponent() throws, exactly as the real
|
|
34
|
+
* client hydrator does, so a caller reproducing that class of bug should assert on the rejection.
|
|
35
|
+
*/
|
|
36
|
+
export declare function hydrateTestApp<Props extends TungstenComponentPropsBase, Component extends TungstenBaseComponent<any, any>, RouteData = undefined>(RootComponent: new (pkg: ConstructPackage<NoInfer<Props>, RouteData>) => Component, ...args: HydrateTestAppArgs<Props>): Promise<HydrateTestApp<Component>>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=hydrateTestApp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrateTestApp.d.ts","sourceRoot":"","sources":["../../src/testing/hydrateTestApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC7B,MAAM,mBAAmB,CAAA;AAO1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAA;AAa1F,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,YAAY,CAAA;AAEnE,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG;IAM9E,WAAW,CAAC,EAAE,KAAK,CAAA;IAEnB,GAAG,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,KAAK,kBAAkB,CAAC,KAAK,SAAS,MAAM,IAAI,MAAM,SAAS,KAAK,GAC9D,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,GACxC,MAAM,KAAK,SAAS,KAAK,GACrB,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,GACxC,CAAC,OAAO,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,CAAA;AAEpE,MAAM,MAAM,cAAc,CAAC,SAAS,SAAS,qBAAqB,IAAI;IAClE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAG7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAIrB,QAAQ,CAAC,UAAU,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAEvD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B,CAAA;AAkGD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAChC,KAAK,SAAS,0BAA0B,EACxC,SAAS,SAAS,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,EACjD,SAAS,GAAG,SAAS,EAErB,aAAa,EAAE,KAAK,GAAG,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK,SAAS,EAClF,GAAG,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,GACnC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CA6HpC"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
2
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
3
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
+
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
|
|
7
|
+
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
|
|
8
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
9
|
+
import { $props, $type } from "../contentNodeSymbols.js";
|
|
10
|
+
import { Instance } from "../Instance/Instance.js";
|
|
11
|
+
import { hydrateRootComponent } from "../hydrate/hydrate.js";
|
|
12
|
+
import { contentTreeToRenderingTree } from "../render/contentTreeToRenderingTree.js";
|
|
13
|
+
import { renderingNodeToHtml } from "../render/renderingTreeToHtml.js";
|
|
14
|
+
import { initStores } from "../Servers/initStores.js";
|
|
15
|
+
import { deleteNodeIfRendered } from "../update/integrateUpdateVdom.js";
|
|
16
|
+
import { UpdateScheduler } from "../update/UpdateScheduler.js";
|
|
17
|
+
import { DomPointer } from "../DomPointer.js";
|
|
18
|
+
import { ensureTestEnvLoaded } from "./ensureTestEnvLoaded.js";
|
|
19
|
+
// hydrate.tsx references several DOM globals directly (Node.COMMENT_NODE, `instanceof Text`, the
|
|
20
|
+
// bare `document`) the way real browser code always can - happy-dom only puts these on its own
|
|
21
|
+
// Window, not on Node.js's global scope. Every hand-written hydration test before this harness
|
|
22
|
+
// bridged them manually; a caller of hydrateTestApp() shouldn't need to know that hydrate() was
|
|
23
|
+
// written assuming a real browser to begin with.
|
|
24
|
+
function bridgeHappyDomGlobals(document) {
|
|
25
|
+
const window = document.defaultView;
|
|
26
|
+
if (window === null) return;
|
|
27
|
+
const globals = globalThis; // eslint-disable-line no-type-assertion/no-type-assertion -- bridging happy-dom's globals onto the global scope
|
|
28
|
+
globals.Node = window.Node;
|
|
29
|
+
globals.Text = window.Text;
|
|
30
|
+
globals.Comment = window.Comment;
|
|
31
|
+
globals.Element = window.Element;
|
|
32
|
+
globals.HTMLElement = window.HTMLElement;
|
|
33
|
+
globals.Document = window.Document;
|
|
34
|
+
globals.document = document;
|
|
35
|
+
globals.window = window;
|
|
36
|
+
}
|
|
37
|
+
var _instance = /*#__PURE__*/new WeakMap();
|
|
38
|
+
var _scheduler = /*#__PURE__*/new WeakMap();
|
|
39
|
+
var _ownsContainer = /*#__PURE__*/new WeakMap();
|
|
40
|
+
var _unmounted = /*#__PURE__*/new WeakMap();
|
|
41
|
+
class HydrateTestAppImplementation {
|
|
42
|
+
constructor(document, container, component, instance, scheduler, ownsContainer, html, mismatches) {
|
|
43
|
+
_defineProperty(this, "document", void 0);
|
|
44
|
+
_defineProperty(this, "container", void 0);
|
|
45
|
+
_defineProperty(this, "component", void 0);
|
|
46
|
+
_defineProperty(this, "html", void 0);
|
|
47
|
+
_defineProperty(this, "mismatches", void 0);
|
|
48
|
+
_classPrivateFieldInitSpec(this, _instance, void 0);
|
|
49
|
+
_classPrivateFieldInitSpec(this, _scheduler, void 0);
|
|
50
|
+
_classPrivateFieldInitSpec(this, _ownsContainer, void 0);
|
|
51
|
+
_classPrivateFieldInitSpec(this, _unmounted, false);
|
|
52
|
+
_defineProperty(this, "resolved", async () => {
|
|
53
|
+
await _classPrivateFieldGet(_scheduler, this).resolved();
|
|
54
|
+
});
|
|
55
|
+
_defineProperty(this, "setProps", async props => {
|
|
56
|
+
if (_classPrivateFieldGet(_unmounted, this)) throw new Error('Cannot set props on an unmounted Tungsten HydrateTestApp.');
|
|
57
|
+
this.component.props = props;
|
|
58
|
+
_classPrivateFieldGet(_instance, this).queueUpdate(this.component);
|
|
59
|
+
await this.resolved();
|
|
60
|
+
});
|
|
61
|
+
_defineProperty(this, "unmount", async () => {
|
|
62
|
+
if (_classPrivateFieldGet(_unmounted, this)) return;
|
|
63
|
+
_classPrivateFieldSet(_unmounted, this, true);
|
|
64
|
+
_classPrivateFieldGet(_scheduler, this).cancelPending();
|
|
65
|
+
let cleanupError;
|
|
66
|
+
try {
|
|
67
|
+
this.component.__delete();
|
|
68
|
+
deleteNodeIfRendered(this.component.__currentContent);
|
|
69
|
+
this.component.__deleted();
|
|
70
|
+
_classPrivateFieldGet(_instance, this).disposeRegisteredComponents();
|
|
71
|
+
await _classPrivateFieldGet(_scheduler, this).resolved();
|
|
72
|
+
} catch (error) {
|
|
73
|
+
cleanupError = error;
|
|
74
|
+
try {
|
|
75
|
+
_classPrivateFieldGet(_instance, this).disposeRegisteredComponents();
|
|
76
|
+
} catch {
|
|
77
|
+
// Preserve the first cleanup failure.
|
|
78
|
+
}
|
|
79
|
+
} finally {
|
|
80
|
+
_classPrivateFieldGet(_scheduler, this).dispose();
|
|
81
|
+
if (_classPrivateFieldGet(_ownsContainer, this)) this.container.remove();else while (this.container.firstChild !== null) this.container.removeChild(this.container.firstChild);
|
|
82
|
+
}
|
|
83
|
+
if (cleanupError !== undefined) throw cleanupError;
|
|
84
|
+
});
|
|
85
|
+
this.document = document;
|
|
86
|
+
this.container = container;
|
|
87
|
+
this.component = component;
|
|
88
|
+
_classPrivateFieldSet(_instance, this, instance);
|
|
89
|
+
_classPrivateFieldSet(_scheduler, this, scheduler);
|
|
90
|
+
_classPrivateFieldSet(_ownsContainer, this, ownsContainer);
|
|
91
|
+
this.html = html;
|
|
92
|
+
this.mismatches = mismatches;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The hydration round trip createTestApp() deliberately doesn't cover: render a component to
|
|
97
|
+
* HTML the way a real server would, parse it with a real HTML parser, hydrate a fresh client
|
|
98
|
+
* instance against the result, and hand back the live, hydrated component - still fully usable
|
|
99
|
+
* via setProps()/resolved(), exactly like createTestApp()'s result.
|
|
100
|
+
*
|
|
101
|
+
* By default `props` renders on both sides, so a passing test proves an ordinary page hydrates
|
|
102
|
+
* clean (`mismatches` empty). Pass `serverProps` to diverge the two passes on purpose and assert
|
|
103
|
+
* on the resulting `mismatches` - the case a one-off "does the reconciler still agree with real
|
|
104
|
+
* served pages" script never could, because nothing fed it markup that didn't already match.
|
|
105
|
+
*
|
|
106
|
+
* A structural mismatch (a different tag, a different number of children) is not something
|
|
107
|
+
* reconcileHydratedAttributes() can fix - hydrateRootComponent() throws, exactly as the real
|
|
108
|
+
* client hydrator does, so a caller reproducing that class of bug should assert on the rejection.
|
|
109
|
+
*/
|
|
110
|
+
export async function hydrateTestApp(RootComponent, ...args) {
|
|
111
|
+
await ensureTestEnvLoaded();
|
|
112
|
+
const options = args[0]; // eslint-disable-line no-type-assertion/no-type-assertion
|
|
113
|
+
const suppliedDocument = options?.document ?? globalThis.document; // eslint-disable-line no-type-assertion/no-type-assertion
|
|
114
|
+
if (suppliedDocument === undefined) {
|
|
115
|
+
// eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
116
|
+
throw new Error('hydrateTestApp() requires options.document when no global document is available.');
|
|
117
|
+
}
|
|
118
|
+
const document = suppliedDocument;
|
|
119
|
+
const ownsContainer = options?.container === undefined;
|
|
120
|
+
const container = options?.container ?? document.createElement('div');
|
|
121
|
+
if (container.ownerDocument !== document) {
|
|
122
|
+
throw new Error('The HydrateTestApp container must belong to options.document.');
|
|
123
|
+
}
|
|
124
|
+
if (container.childNodes.length > 0) {
|
|
125
|
+
throw new Error('The HydrateTestApp container must be empty before hydrating.');
|
|
126
|
+
}
|
|
127
|
+
if (ownsContainer) {
|
|
128
|
+
if (document.body === null) {
|
|
129
|
+
// eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
130
|
+
throw new Error('The supplied document must have a body element.');
|
|
131
|
+
}
|
|
132
|
+
document.body.appendChild(container);
|
|
133
|
+
}
|
|
134
|
+
const clientProps = options?.props ?? {}; // eslint-disable-line no-type-assertion/no-type-assertion
|
|
135
|
+
const serverProps = options?.serverProps ?? clientProps;
|
|
136
|
+
const location = options?.location ?? '/';
|
|
137
|
+
const globalData = options?.globalData ?? {}; // eslint-disable-line no-type-assertion/no-type-assertion
|
|
138
|
+
const matchedRouteInfo = {
|
|
139
|
+
key: null,
|
|
140
|
+
params: options?.routeParams ?? {},
|
|
141
|
+
content: null,
|
|
142
|
+
...(options !== undefined && 'routeData' in options ? {
|
|
143
|
+
data: options.routeData
|
|
144
|
+
} : {})
|
|
145
|
+
};
|
|
146
|
+
const instanceConfig = {
|
|
147
|
+
prod: false,
|
|
148
|
+
useRootComponent: true,
|
|
149
|
+
clientSideNav: false,
|
|
150
|
+
siteBasePath: '/',
|
|
151
|
+
staticSite: false,
|
|
152
|
+
csr: options?.csr ?? false
|
|
153
|
+
};
|
|
154
|
+
const emptyRoutes = {}; // eslint-disable-line no-type-assertion/no-type-assertion -- not exercised by hydration tests
|
|
155
|
+
// eslint-disable-next-line no-type-assertion/no-type-assertion -- rootToHtml.ts builds a root content node the same way
|
|
156
|
+
const componentNode = {
|
|
157
|
+
[$type]: RootComponent,
|
|
158
|
+
[$props]: serverProps
|
|
159
|
+
};
|
|
160
|
+
// Server pass: a throwaway Instance whose only job is producing the HTML a real server would
|
|
161
|
+
// have sent for `serverProps`. Never returned, never touched again once `html` is captured.
|
|
162
|
+
const ssrScheduler = new UpdateScheduler();
|
|
163
|
+
let html;
|
|
164
|
+
try {
|
|
165
|
+
const {
|
|
166
|
+
internalStore,
|
|
167
|
+
stores,
|
|
168
|
+
storeSubscriptions
|
|
169
|
+
} = initStores(location, null, globalData, matchedRouteInfo);
|
|
170
|
+
const ssrInstance = new Instance(location, instanceConfig, null, emptyRoutes, emptyRoutes,
|
|
171
|
+
// eslint-disable-line no-type-assertion/no-type-assertion
|
|
172
|
+
internalStore, stores, storeSubscriptions, globalData, matchedRouteInfo, {
|
|
173
|
+
document,
|
|
174
|
+
window: document.defaultView,
|
|
175
|
+
scheduler: ssrScheduler,
|
|
176
|
+
navigation: false
|
|
177
|
+
});
|
|
178
|
+
for (const override of options?.stores ?? []) {
|
|
179
|
+
const store = override.registration.getStore(ssrInstance.stores);
|
|
180
|
+
await override.initialize(store);
|
|
181
|
+
}
|
|
182
|
+
const renderingTree = await contentTreeToRenderingTree(componentNode, null, ssrInstance, false);
|
|
183
|
+
const headData = {
|
|
184
|
+
found: false,
|
|
185
|
+
instance: ssrInstance,
|
|
186
|
+
clientImportAliases: {},
|
|
187
|
+
importAliases: {},
|
|
188
|
+
compilationLocation: '',
|
|
189
|
+
dev: false,
|
|
190
|
+
tungstenPublicEnv: undefined,
|
|
191
|
+
siteBasePath: '',
|
|
192
|
+
hmr: true,
|
|
193
|
+
csr: instanceConfig.csr
|
|
194
|
+
};
|
|
195
|
+
html = await renderingNodeToHtml(renderingTree, false, headData, null);
|
|
196
|
+
} finally {
|
|
197
|
+
ssrScheduler.dispose();
|
|
198
|
+
}
|
|
199
|
+
// A real HTML parser - the same algorithm a browser runs before hydrate() ever sees the page
|
|
200
|
+
// - not a comparison against the string above, so browser parsing quirks (an auto-closed <p>,
|
|
201
|
+
// an inserted <tbody>) surface exactly as they would in production.
|
|
202
|
+
container.innerHTML = html;
|
|
203
|
+
bridgeHappyDomGlobals(document);
|
|
204
|
+
const scheduler = new UpdateScheduler();
|
|
205
|
+
const {
|
|
206
|
+
internalStore,
|
|
207
|
+
stores,
|
|
208
|
+
storeSubscriptions
|
|
209
|
+
} = initStores(location, null, globalData, matchedRouteInfo);
|
|
210
|
+
const runtimeContext = {
|
|
211
|
+
document,
|
|
212
|
+
window: document.defaultView,
|
|
213
|
+
scheduler,
|
|
214
|
+
navigation: false
|
|
215
|
+
};
|
|
216
|
+
const instance = new Instance(location, instanceConfig, null, emptyRoutes, emptyRoutes,
|
|
217
|
+
// eslint-disable-line no-type-assertion/no-type-assertion
|
|
218
|
+
internalStore, stores, storeSubscriptions, globalData, matchedRouteInfo, runtimeContext);
|
|
219
|
+
try {
|
|
220
|
+
for (const override of options?.stores ?? []) {
|
|
221
|
+
const store = override.registration.getStore(instance.stores);
|
|
222
|
+
await override.initialize(store);
|
|
223
|
+
}
|
|
224
|
+
const meta = {
|
|
225
|
+
insideForm: false,
|
|
226
|
+
mismatches: []
|
|
227
|
+
};
|
|
228
|
+
const domPointer = new DomPointer(container, 0);
|
|
229
|
+
const component = await hydrateRootComponent(instance, RootComponent, domPointer, meta, clientProps, options?.routeParams, options?.routeData);
|
|
230
|
+
return new HydrateTestAppImplementation(document, container, component, instance, scheduler, ownsContainer, html, meta.mismatches);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
try {
|
|
233
|
+
instance.disposeRegisteredComponents();
|
|
234
|
+
} catch {
|
|
235
|
+
// Preserve the mount failure.
|
|
236
|
+
}
|
|
237
|
+
scheduler.dispose();
|
|
238
|
+
while (container.firstChild !== null) container.removeChild(container.firstChild);
|
|
239
|
+
if (ownsContainer) container.remove();
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { TungstenBaseComponent, TungstenBaseComponentType } from '../Components.jsx';
|
|
1
|
+
import type { ConstructPackage, TungstenBaseComponent, TungstenBaseComponentType, TungstenComponentPropsBase } from '../Components.jsx';
|
|
2
2
|
export { ensureTestEnvLoaded, testEnvVariableName } from './ensureTestEnvLoaded.js';
|
|
3
|
+
export { hydrateTestApp, type HydrateTestApp, type HydrateTestAppOptions } from './hydrateTestApp.js';
|
|
3
4
|
import type { TrueStore } from '../Store/makeStore.js';
|
|
4
5
|
export type ComponentProps<ComponentType extends TungstenBaseComponentType<any, any>> = InstanceType<ComponentType>['props'];
|
|
5
6
|
export type TestStoreRegistration<Schema extends object> = {
|
|
@@ -29,8 +30,8 @@ export type TestApp<Component extends TungstenBaseComponent> = {
|
|
|
29
30
|
setProps(props: Component['props']): Promise<void>;
|
|
30
31
|
unmount(): Promise<void>;
|
|
31
32
|
};
|
|
32
|
-
type CreateTestAppArgs<Props extends object> = object extends Props ? [options?: TestAppOptions<Props>] : keyof Props extends never ? [options?: TestAppOptions<Props>] : [options: TestAppOptions<Props> & {
|
|
33
|
+
export type CreateTestAppArgs<Props extends object> = object extends Props ? [options?: TestAppOptions<Props>] : keyof Props extends never ? [options?: TestAppOptions<Props>] : [options: TestAppOptions<Props> & {
|
|
33
34
|
props: Props;
|
|
34
35
|
}];
|
|
35
|
-
export declare function createTestApp<
|
|
36
|
+
export declare function createTestApp<Props extends TungstenComponentPropsBase, Component extends TungstenBaseComponent<any, any>, RouteData = undefined>(RootComponent: new (pkg: ConstructPackage<NoInfer<Props>, RouteData>) => Component, ...args: CreateTestAppArgs<Props>): Promise<TestApp<Component>>;
|
|
36
37
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,qBAAqB,EACrB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,EAC7B,MAAM,mBAAmB,CAAA;AAM1B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnF,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAErG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAWtD,MAAM,MAAM,cAAc,CACtB,aAAa,SAAS,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,IACzD,YAAY,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAA;AAExC,MAAM,MAAM,qBAAqB,CAAC,MAAM,SAAS,MAAM,IAAI;IACvD,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,CAAC,MAAM,CAAC,CAAA;CAChE,CAAA;AAED,MAAM,MAAM,SAAS,CAAC,MAAM,SAAS,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,CAAA;AAEhE,MAAM,MAAM,iBAAiB,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,IAAI;IAC5D,YAAY,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAA;IAC3C,UAAU,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACjE,CAAA;AAED,wBAAgB,SAAS,CAAC,MAAM,SAAS,MAAM,EAC3C,YAAY,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAC3C,UAAU,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC/D,iBAAiB,CAAC,MAAM,CAAC,CAE3B;AAED,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,MAAM,IAAI;IAC/C,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,SAAS,CAAC,EAAE,WAAW,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,MAAM,CAAC,EAAE,SAAS,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,OAAO,CAAC,SAAS,SAAS,qBAAqB,IAAI;IAC3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAE7B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,MAAM,IAAI,MAAM,SAAS,KAAK,GACpE,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,GACjC,MAAM,KAAK,SAAS,KAAK,GACrB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,GACjC,CAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,CAAA;AAqE7D,wBAAsB,aAAa,CAC/B,KAAK,SAAS,0BAA0B,EACxC,SAAS,SAAS,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,EACjD,SAAS,GAAG,SAAS,EAarB,aAAa,EAAE,KAAK,GAAG,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK,SAAS,EAClF,GAAG,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAqH7B"}
|
package/dist/testing/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { Instance } from "../Instance/Instance.js";
|
|
|
10
10
|
import { initStores } from "../Servers/initStores.js";
|
|
11
11
|
import { ensureTestEnvLoaded } from "./ensureTestEnvLoaded.js";
|
|
12
12
|
export { ensureTestEnvLoaded, testEnvVariableName } from "./ensureTestEnvLoaded.js";
|
|
13
|
+
export { hydrateTestApp } from "./hydrateTestApp.js";
|
|
13
14
|
import { createTungstenRootComponent, deleteTungstenRoot } from "../update/integrateUpdateVdom.js";
|
|
14
15
|
import { UpdateScheduler } from "../update/UpdateScheduler.js";
|
|
15
16
|
export function testStore(registration, initialize) {
|
|
@@ -73,7 +74,19 @@ class TestAppImplementation {
|
|
|
73
74
|
_classPrivateFieldSet(_ownsContainer, this, ownsContainer);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
|
-
export async function createTestApp(
|
|
77
|
+
export async function createTestApp(
|
|
78
|
+
// NoInfer applies to Props only inside the constructor parameter, not to
|
|
79
|
+
// RootComponent as a whole - so Props is inferred from `props` alone
|
|
80
|
+
// (a generic component's own type parameters can then be inferred from a
|
|
81
|
+
// typed props value, the same way `const x: TungstenBaseComponentType<
|
|
82
|
+
// BoundProps<Form, 'value'>> = BoundValue` already type-checks), while
|
|
83
|
+
// Component is still inferred from the constructor's return type, so
|
|
84
|
+
// `.component` on the result keeps the concrete class (state, methods),
|
|
85
|
+
// not the erased TungstenBaseComponent base. Without the NoInfer, Props
|
|
86
|
+
// is inferred from RootComponent first - a bare class reference with no
|
|
87
|
+
// type arguments - so a generic component's own parameters collapse to
|
|
88
|
+
// their constraints before `props` is ever considered.
|
|
89
|
+
RootComponent, ...args) {
|
|
77
90
|
await ensureTestEnvLoaded();
|
|
78
91
|
const options = args[0];
|
|
79
92
|
const suppliedDocument = options?.document ?? globalThis.document;
|
|
@@ -124,7 +137,8 @@ export async function createTestApp(RootComponent, ...args) {
|
|
|
124
137
|
useRootComponent: true,
|
|
125
138
|
clientSideNav: false,
|
|
126
139
|
siteBasePath: '/',
|
|
127
|
-
staticSite: false
|
|
140
|
+
staticSite: false,
|
|
141
|
+
csr: false
|
|
128
142
|
};
|
|
129
143
|
const emptyRoutes = {};
|
|
130
144
|
const instance = new Instance(location, instanceConfig, null, emptyRoutes, emptyRoutes, internalStore, stores, storeSubscriptions, globalData, matchedRouteInfo, runtimeContext);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type TimeProfiler = {
|
|
2
|
+
timeProfile: <T>(name: string, task: () => T) => T;
|
|
3
|
+
timeProfileAsync: <T>(name: string, task: () => T | Promise<T>) => Promise<T>;
|
|
4
|
+
};
|
|
5
|
+
export declare function createTimeProfiler(profiling?: boolean): TimeProfiler;
|
|
6
|
+
//# sourceMappingURL=timeProfiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeProfiler.d.ts","sourceRoot":"","sources":["../src/timeProfiler.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,YAAY,GAAG;IACvB,WAAW,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IAClD,gBAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAChF,CAAA;AAMD,wBAAgB,kBAAkB,CAAC,SAAS,UAAO,GAAG,YAAY,CAqBjE"}
|