@abide/abide 0.49.0 → 0.50.1
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/AGENTS.md +564 -437
- package/CHANGELOG.md +183 -0
- package/README.md +165 -202
- package/package.json +14 -5
- package/src/abideLsp.ts +5 -6
- package/src/abideResolverPlugin.ts +197 -169
- package/src/build.ts +79 -56
- package/src/buildDisconnected.ts +0 -2
- package/src/checkAbide.ts +12 -2
- package/src/devEntry.ts +113 -28
- package/src/discoveryEntry.ts +3 -2
- package/src/lib/bundle/disconnected.abide +69 -73
- package/src/lib/bundle/infoPlist.ts +13 -7
- package/src/lib/bundle/spawnEmbeddedServer.ts +13 -4
- package/src/lib/bundle/waitForServer.ts +6 -1
- package/src/lib/mcp/mcpTools.ts +15 -6
- package/src/lib/server/error.ts +6 -6
- package/src/lib/server/json.ts +17 -3
- package/src/lib/server/rpc/defineRpc.ts +58 -24
- package/src/lib/server/rpc/parseArgs.ts +98 -13
- package/src/lib/server/rpc/resolveRpcJsonSchema.ts +28 -0
- package/src/lib/server/rpc/types/RpcHelper.ts +75 -105
- package/src/lib/server/rpc/types/RpcRegistryEntry.ts +24 -9
- package/src/lib/server/rpc/validationError.ts +1 -1
- package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +0 -15
- package/src/lib/server/runtime/buildCacheSnapshot.ts +10 -9
- package/src/lib/server/runtime/buildInspectorSurface.ts +6 -4
- package/src/lib/server/runtime/buildOpenApiSpec.ts +55 -11
- package/src/lib/server/runtime/buildPreloadManifest.ts +12 -10
- package/src/lib/server/runtime/createAppAssetServer.ts +18 -15
- package/src/lib/server/runtime/createAppRouteResolver.ts +145 -0
- package/src/lib/server/runtime/createPlumbingRouter.ts +212 -0
- package/src/lib/server/runtime/createRouteDispatcher.ts +4 -10
- package/src/lib/server/runtime/createServer.ts +120 -324
- package/src/lib/server/runtime/createUiPageRenderer.ts +137 -26
- package/src/lib/server/runtime/devClientFingerprint.ts +19 -34
- package/src/lib/server/runtime/installAmbientScopeStore.ts +30 -9
- package/src/lib/server/runtime/logExposedSurfaces.ts +8 -7
- package/src/lib/server/runtime/pathStore.ts +15 -0
- package/src/lib/server/runtime/registryManifests.ts +1 -1
- package/src/lib/server/runtime/renderCellBarrierStore.ts +15 -0
- package/src/lib/server/runtime/runWithRequestScope.ts +3 -0
- package/src/lib/server/runtime/serializeCacheSnapshot.ts +6 -4
- package/src/lib/server/runtime/snapshotEntryFromCache.ts +14 -14
- package/src/lib/server/runtime/streamCacheResolutions.ts +14 -7
- package/src/lib/server/runtime/streamFromIterator.ts +30 -2
- package/src/lib/server/runtime/textResponse.ts +23 -0
- package/src/lib/server/runtime/types/DevReloadStamp.ts +6 -10
- package/src/lib/server/runtime/types/InspectorCacheEntry.ts +1 -1
- package/src/lib/server/runtime/types/RequestStore.ts +27 -0
- package/src/lib/server/runtime/warnUnguardedMcp.ts +15 -5
- package/src/lib/server/sockets/createSocketDispatcher.ts +9 -11
- package/src/lib/server/sockets/defineSocket.ts +5 -4
- package/src/lib/server/sse.ts +5 -1
- package/src/lib/shared/ASYNC_CELL.ts +5 -0
- package/src/lib/shared/DEV_REBUILD_PATH.ts +6 -0
- package/src/lib/shared/HTTP_METHODS.ts +6 -0
- package/src/lib/shared/HttpError.ts +1 -5
- package/src/lib/shared/MCP_PATH.ts +6 -0
- package/src/lib/shared/PROXIED_SERVER_SUBDIRS.ts +15 -0
- package/src/lib/shared/REF_JSON_TAGS.ts +13 -1
- package/src/lib/shared/RPC_SHIM_GLOBALS.ts +9 -0
- package/src/lib/shared/activeCacheStore.ts +1 -0
- package/src/lib/shared/activePage.ts +1 -0
- package/src/lib/shared/buildArtifact.ts +4 -1
- package/src/lib/shared/buildSocketOverChannel.ts +4 -3
- package/src/lib/shared/bundleGraphFromMetafile.ts +68 -0
- package/src/lib/shared/cache.ts +156 -131
- package/src/lib/shared/changeAffectsClient.ts +12 -7
- package/src/lib/shared/createCacheStore.ts +31 -8
- package/src/lib/shared/createLifecycleChannel.ts +7 -1
- package/src/lib/shared/createReachable.ts +47 -78
- package/src/lib/shared/createRemoteFunction.ts +52 -30
- package/src/lib/shared/createRpcServerProgram.ts +820 -0
- package/src/lib/shared/decodeRefJson.ts +4 -4
- package/src/lib/shared/decodeResponse.ts +2 -2
- package/src/lib/shared/decodeWireBody.ts +35 -0
- package/src/lib/shared/detectRpcMethod.ts +8 -1
- package/src/lib/shared/done.ts +8 -2
- package/src/lib/shared/encodeRefJson.ts +4 -4
- package/src/lib/shared/encodeWireBody.ts +18 -0
- package/src/lib/{server/rpc → shared}/fieldErrorsFromIssues.ts +5 -1
- package/src/lib/shared/generateDeclarations.ts +72 -0
- package/src/lib/shared/hasSeedableRequest.ts +25 -0
- package/src/lib/shared/hydrationWindow.ts +53 -0
- package/src/lib/shared/isAsyncCell.ts +11 -0
- package/src/lib/shared/isAsyncIterable.ts +8 -0
- package/src/lib/shared/isSubscribable.ts +3 -3
- package/src/lib/shared/isThenable.ts +9 -0
- package/src/lib/shared/jsonSchemaForType.ts +258 -0
- package/src/lib/shared/lenientDecode.ts +15 -0
- package/src/lib/shared/loadProjectTsConfig.ts +28 -0
- package/src/lib/shared/markFrameworkSourcesIgnored.ts +1 -1
- package/src/lib/shared/matchRoute.ts +4 -14
- package/src/lib/shared/peek.ts +14 -0
- package/src/lib/shared/pending.ts +9 -6
- package/src/lib/shared/pendingAsyncCellsSlot.ts +13 -0
- package/src/lib/shared/prepareRpcModule.ts +91 -93
- package/src/lib/shared/prepareSocketModule.ts +3 -2
- package/src/lib/shared/probeRegistries.ts +5 -18
- package/src/lib/shared/reachable.ts +7 -10
- package/src/lib/shared/refresh.ts +12 -2
- package/src/lib/shared/refreshing.ts +8 -2
- package/src/lib/shared/resolvedCellsSlot.ts +13 -0
- package/src/lib/shared/reviveWireField.ts +49 -0
- package/src/lib/shared/reviveWireOutput.ts +36 -0
- package/src/lib/shared/rpcServerForRoot.ts +25 -0
- package/src/lib/shared/scanPages.ts +25 -0
- package/src/lib/shared/snapshotShippable.ts +8 -7
- package/src/lib/shared/streamedCellsSlot.ts +14 -0
- package/src/lib/shared/subscribableFromResponse.ts +4 -4
- package/src/lib/shared/subscribableProbes.ts +1 -1
- package/src/lib/shared/tailProbeSlot.ts +1 -1
- package/src/lib/shared/types/AsyncComputed.ts +20 -0
- package/src/lib/shared/types/AsyncState.ts +13 -0
- package/src/lib/shared/types/CacheEntry.ts +7 -7
- package/src/lib/shared/types/CacheOptions.ts +23 -37
- package/src/lib/shared/types/CachePolicy.ts +25 -0
- package/src/lib/shared/types/CacheSnapshotEntry.ts +6 -5
- package/src/lib/shared/types/ErrorJsonSchemas.ts +8 -0
- package/src/lib/shared/types/HttpMethod.ts +3 -1
- package/src/lib/shared/types/InputCoercion.ts +17 -0
- package/src/lib/shared/types/{Subscribable.ts → NamedAsyncIterable.ts} +1 -1
- package/src/lib/shared/types/OutputWirePlan.ts +17 -0
- package/src/lib/shared/types/PagesScan.ts +7 -0
- package/src/lib/shared/types/PendingAsyncCells.ts +10 -0
- package/src/lib/shared/types/RawRemoteFunction.ts +6 -0
- package/src/lib/shared/types/RemoteCallable.ts +8 -7
- package/src/lib/shared/types/RemoteFunction.ts +16 -15
- package/src/lib/shared/types/ResolvedCells.ts +11 -0
- package/src/lib/shared/types/ReturnBody.ts +15 -0
- package/src/lib/shared/types/RpcBuildStamps.ts +23 -0
- package/src/lib/shared/types/RpcErrorGuard.ts +3 -8
- package/src/lib/shared/types/Socket.ts +4 -4
- package/src/lib/shared/types/SsrPayload.ts +5 -1
- package/src/lib/shared/types/StreamPolicy.ts +11 -0
- package/src/lib/shared/types/StreamedCells.ts +19 -0
- package/src/lib/shared/types/StreamedResolution.ts +24 -6
- package/src/lib/shared/types/TailHooks.ts +1 -1
- package/src/lib/shared/types/WireKind.ts +11 -0
- package/src/lib/shared/validationHttpError.ts +33 -0
- package/src/lib/shared/warmSeedKey.ts +16 -0
- package/src/lib/shared/wireJsonReplacer.ts +30 -0
- package/src/lib/shared/writeRpcDts.ts +11 -1
- package/src/lib/shared/writeTestSocketsDts.ts +1 -1
- package/src/lib/test/createTestApp.ts +19 -1
- package/src/lib/ui/README.md +1 -1
- package/src/lib/ui/activePendingCells.ts +14 -0
- package/src/lib/ui/compile/BLOCK_KEYWORDS.ts +21 -0
- package/src/lib/ui/compile/SSR_ESCAPE.ts +4 -1
- package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +35 -8
- package/src/lib/ui/compile/abideUiPlugin.ts +19 -2
- package/src/lib/ui/compile/analyzeComponent.ts +89 -6
- package/src/lib/ui/compile/assignmentTargetNames.ts +54 -0
- package/src/lib/ui/compile/asyncInterpolationFields.ts +152 -0
- package/src/lib/ui/compile/asyncValuePositionError.ts +21 -0
- package/src/lib/ui/compile/asyncValuePositionInterpolations.ts +64 -0
- package/src/lib/ui/compile/attrLiftPosition.ts +18 -0
- package/src/lib/ui/compile/cachedSourceFile.ts +40 -0
- package/src/lib/ui/compile/catchBinding.ts +7 -5
- package/src/lib/ui/compile/classifyInterpolationType.ts +46 -0
- package/src/lib/ui/compile/collectAbideDiagnostics.ts +96 -0
- package/src/lib/ui/compile/compileComponent.ts +19 -3
- package/src/lib/ui/compile/compileModule.ts +27 -58
- package/src/lib/ui/compile/compileSSR.ts +51 -12
- package/src/lib/ui/compile/compileShadow.ts +145 -18
- package/src/lib/ui/compile/composeProps.ts +12 -2
- package/src/lib/ui/compile/createShadowLanguageService.ts +116 -68
- package/src/lib/ui/compile/createShadowProgram.ts +35 -6
- package/src/lib/ui/compile/declaredNames.ts +36 -0
- package/src/lib/ui/compile/desugarSignals.ts +418 -36
- package/src/lib/ui/compile/expressionIsPrefixEvaluable.ts +19 -0
- package/src/lib/ui/compile/generateBuild.ts +52 -9
- package/src/lib/ui/compile/generateSSR.ts +242 -43
- package/src/lib/ui/compile/hoistableAwaits.ts +193 -0
- package/src/lib/ui/compile/hoistableChildRenders.ts +112 -0
- package/src/lib/ui/compile/interpolatedTemplateLiteral.ts +3 -1
- package/src/lib/ui/compile/interpolationClassifierForRoot.ts +37 -0
- package/src/lib/ui/compile/isSpuriousAsyncReadDiagnostic.ts +174 -0
- package/src/lib/ui/compile/liftAsyncSubExpressions.ts +166 -0
- package/src/lib/ui/compile/lowerAsyncInterpolations.ts +92 -0
- package/src/lib/ui/compile/lowerContext.ts +10 -0
- package/src/lib/ui/compile/lowerDocAccess.ts +26 -23
- package/src/lib/ui/compile/lowerScript.ts +40 -4
- package/src/lib/ui/compile/nodeAtShadowOffset.ts +28 -0
- package/src/lib/ui/compile/parseTemplate.ts +18 -1092
- package/src/lib/ui/compile/parseTemplateRecovering.ts +1385 -0
- package/src/lib/ui/compile/referencedIdentifiers.ts +35 -0
- package/src/lib/ui/compile/renameSignalRefs.ts +21 -22
- package/src/lib/ui/compile/seedTypeClassifierForRoot.ts +65 -0
- package/src/lib/ui/compile/shadowInterpolationClassifier.ts +47 -0
- package/src/lib/ui/compile/sourceFileOptionsSignature.ts +20 -0
- package/src/lib/ui/compile/structuralHeadTokens.ts +107 -0
- package/src/lib/ui/compile/templateSemanticTokens.ts +21 -0
- package/src/lib/ui/compile/templateStartOffset.ts +15 -0
- package/src/lib/ui/compile/tryPlan.ts +4 -3
- package/src/lib/ui/compile/types/AnalyzedComponent.ts +4 -0
- package/src/lib/ui/compile/types/AsyncInterpolationField.ts +19 -0
- package/src/lib/ui/compile/types/InterpolationClassifier.ts +12 -0
- package/src/lib/ui/compile/types/InterpolationKind.ts +7 -0
- package/src/lib/ui/compile/types/ParseDiagnostic.ts +8 -0
- package/src/lib/ui/compile/types/SeedTypeClassifier.ts +15 -0
- package/src/lib/ui/compile/types/TemplateNode.ts +36 -4
- package/src/lib/ui/compile/types/ValuePositionInterpolation.ts +13 -0
- package/src/lib/ui/compile/writtenTemplateNames.ts +84 -0
- package/src/lib/ui/computed.ts +28 -1
- package/src/lib/ui/createScope.ts +35 -68
- package/src/lib/ui/dom/anchoredBranch.ts +142 -0
- package/src/lib/ui/dom/appendText.ts +8 -3
- package/src/lib/ui/dom/awaitBlock.ts +43 -94
- package/src/lib/ui/dom/bindProp.ts +22 -0
- package/src/lib/ui/dom/bindableProp.ts +47 -0
- package/src/lib/ui/dom/cellPending.ts +24 -0
- package/src/lib/ui/dom/disposeRange.ts +2 -1
- package/src/lib/ui/dom/each.ts +26 -4
- package/src/lib/ui/dom/eachAsync.ts +39 -3
- package/src/lib/ui/dom/fillBoundary.ts +2 -3
- package/src/lib/ui/dom/fillRange.ts +4 -4
- package/src/lib/ui/dom/hydrate.ts +6 -12
- package/src/lib/ui/dom/isComment.ts +1 -1
- package/src/lib/ui/dom/matchingRangeClose.ts +29 -0
- package/src/lib/ui/dom/mount.ts +1 -2
- package/src/lib/ui/dom/mountChild.ts +9 -40
- package/src/lib/ui/dom/mountRange.ts +2 -3
- package/src/lib/ui/dom/mountStreamedChild.ts +84 -0
- package/src/lib/ui/dom/mountSwappableRange.ts +46 -4
- package/src/lib/ui/dom/mutateDocContainer.ts +65 -0
- package/src/lib/ui/dom/on.ts +2 -2
- package/src/lib/ui/dom/readCell.ts +40 -0
- package/src/lib/ui/dom/switchBlock.ts +30 -7
- package/src/lib/ui/dom/tryBlock.ts +230 -66
- package/src/lib/ui/dom/types/SwitchCase.ts +5 -1
- package/src/lib/ui/dom/when.ts +12 -2
- package/src/lib/ui/dom/withScope.ts +2 -2
- package/src/lib/ui/finalizeStreamedChildren.ts +89 -0
- package/src/lib/ui/flight.ts +56 -0
- package/src/lib/ui/html.ts +12 -1
- package/src/lib/ui/isolateCellBarrier.ts +17 -0
- package/src/lib/ui/linked.ts +48 -2
- package/src/lib/ui/remoteProxy.ts +84 -159
- package/src/lib/ui/renderChain.ts +49 -13
- package/src/lib/ui/renderToStream.ts +22 -18
- package/src/lib/ui/resumeSeedScript.ts +1 -1
- package/src/lib/ui/router.ts +63 -36
- package/src/lib/ui/runtime/AsyncCellError.ts +20 -0
- package/src/lib/ui/runtime/CELL_SEED.ts +14 -0
- package/src/lib/ui/runtime/CURRENT_BOUNDARY.ts +11 -0
- package/src/lib/ui/runtime/CURRENT_PATH.ts +29 -0
- package/src/lib/ui/runtime/RENDER.ts +10 -7
- package/src/lib/ui/runtime/RESUME.ts +4 -4
- package/src/lib/ui/runtime/STREAMED_CELLS.ts +57 -0
- package/src/lib/ui/runtime/ambientPathBacking.ts +32 -0
- package/src/lib/ui/runtime/applyPatchToTree.ts +1 -1
- package/src/lib/ui/runtime/blockId.ts +31 -0
- package/src/lib/ui/runtime/boundaryFor.ts +11 -0
- package/src/lib/ui/runtime/cellBarrierBacking.ts +30 -0
- package/src/lib/ui/runtime/createAsyncCell.ts +300 -0
- package/src/lib/ui/runtime/createDoc.ts +3 -42
- package/src/lib/ui/runtime/createEffectNode.ts +9 -0
- package/src/lib/ui/runtime/enterRenderPass.ts +5 -4
- package/src/lib/ui/runtime/flushEffects.ts +16 -6
- package/src/lib/ui/runtime/isAsyncFunction.ts +14 -0
- package/src/lib/ui/runtime/nextBlockId.ts +8 -7
- package/src/lib/ui/runtime/renderPath.ts +16 -0
- package/src/lib/ui/runtime/types/Boundary.ts +9 -0
- package/src/lib/ui/runtime/types/RenderContext.ts +9 -7
- package/src/lib/ui/runtime/types/SsrRender.ts +9 -2
- package/src/lib/ui/runtime/types/UiComponent.ts +1 -5
- package/src/lib/ui/runtime/withOptionalPath.ts +8 -0
- package/src/lib/ui/runtime/withPath.ts +16 -0
- package/src/lib/ui/runtime/withPathFrom.ts +20 -0
- package/src/lib/ui/seedStreamedResolution.ts +31 -6
- package/src/lib/ui/settleAsyncCells.ts +24 -0
- package/src/lib/ui/socketProxy.ts +1 -1
- package/src/lib/ui/startClient.ts +16 -31
- package/src/lib/ui/trackedComputed.ts +68 -0
- package/src/lib/ui/types/Scope.ts +8 -24
- package/src/lib/ui/watch.ts +3 -3
- package/src/serverEntry.ts +14 -0
- package/template/src/server/rpc/getHello.ts +15 -13
- package/template/test/app.test.ts +1 -1
- package/src/lib/server/runtime/devHotModuleResponse.ts +0 -41
- package/src/lib/shared/DEV_HOT_PREFIX.ts +0 -7
- package/src/lib/shared/UNREACHABLE_STATUSES.ts +0 -13
- package/src/lib/shared/hasReplayableRequest.ts +0 -17
- package/src/lib/shared/hydratingSlot.ts +0 -12
- package/src/lib/shared/outboxProbeSlot.ts +0 -20
- package/src/lib/shared/types/Outbox.ts +0 -9
- package/src/lib/shared/types/OutboxEntry.ts +0 -27
- package/src/lib/shared/types/SmartReadOptions.ts +0 -36
- package/src/lib/shared/wakeHydrationPeeks.ts +0 -20
- package/src/lib/ui/COMPONENT_WRAPPER_PREFIX.ts +0 -5
- package/src/lib/ui/compile/REACTIVE_CALLEES.ts +0 -11
- package/src/lib/ui/compile/assertRuntimeHelpersBound.ts +0 -80
- package/src/lib/ui/compile/markupTokens.ts +0 -313
- package/src/lib/ui/compile/structuralBlockTokens.ts +0 -100
- package/src/lib/ui/dom/applyResolved.ts +0 -87
- package/src/lib/ui/dom/mutateDocArray.ts +0 -38
- package/src/lib/ui/dom/scopeLabel.ts +0 -21
- package/src/lib/ui/dom/text.ts +0 -20
- package/src/lib/ui/history.ts +0 -108
- package/src/lib/ui/installHotBridge.ts +0 -95
- package/src/lib/ui/installInspectorBridge.ts +0 -140
- package/src/lib/ui/outbox.ts +0 -35
- package/src/lib/ui/persist.ts +0 -115
- package/src/lib/ui/rpcOutbox/createOutboxQueue.ts +0 -281
- package/src/lib/ui/rpcOutbox/outboxRegistry.ts +0 -69
- package/src/lib/ui/runtime/PATCH_BUS.ts +0 -28
- package/src/lib/ui/runtime/captureModelDoc.ts +0 -43
- package/src/lib/ui/runtime/hotInstances.ts +0 -10
- package/src/lib/ui/runtime/hotReloadEnabled.ts +0 -8
- package/src/lib/ui/runtime/hotReplace.ts +0 -38
- package/src/lib/ui/runtime/liveScopes.ts +0 -15
- package/src/lib/ui/runtime/localStoragePersistence.ts +0 -47
- package/src/lib/ui/runtime/registerHotInstance.ts +0 -23
- package/src/lib/ui/runtime/seedModelDoc.ts +0 -26
- package/src/lib/ui/runtime/types/HotInstance.ts +0 -22
- package/src/lib/ui/runtime/types/PatchEvent.ts +0 -16
- package/src/lib/ui/seedResolved.ts +0 -28
- package/src/lib/ui/sync.ts +0 -48
- package/src/lib/ui/types/History.ts +0 -14
- package/src/lib/ui/types/PersistHandle.ts +0 -11
- package/src/lib/ui/types/PersistenceStore.ts +0 -12
- package/src/lib/ui/types/ResolvedFrame.ts +0 -15
- package/src/lib/ui/types/SyncTransport.ts +0 -13
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import ts from 'typescript'
|
|
2
|
+
import { asyncValuePositionError } from './asyncValuePositionError.ts'
|
|
3
|
+
import { asyncValuePositionInterpolations } from './asyncValuePositionInterpolations.ts'
|
|
4
|
+
import { classifyInterpolationType } from './classifyInterpolationType.ts'
|
|
2
5
|
import type { ShadowProgram } from './createShadowProgram.ts'
|
|
6
|
+
import { isSpuriousAsyncReadDiagnostic } from './isSpuriousAsyncReadDiagnostic.ts'
|
|
7
|
+
import { nodeAtShadowOffset } from './nodeAtShadowOffset.ts'
|
|
8
|
+
import { parseTemplateRecovering } from './parseTemplateRecovering.ts'
|
|
3
9
|
import { remapShadowDiagnostic } from './remapShadowDiagnostic.ts'
|
|
10
|
+
import { sourceToShadowOffset } from './sourceToShadowOffset.ts'
|
|
11
|
+
import { templateStartOffset } from './templateStartOffset.ts'
|
|
4
12
|
import type { AbideDiagnostic } from './types/AbideDiagnostic.ts'
|
|
13
|
+
import type { ShadowMapping } from './types/CompiledShadow.ts'
|
|
5
14
|
|
|
6
15
|
/*
|
|
7
16
|
Runs the shadow program's type-checker over every `.abide` shadow and relocates
|
|
@@ -12,6 +21,7 @@ Shared by `abide check` (one-shot render) and the LSP (per-file publish).
|
|
|
12
21
|
*/
|
|
13
22
|
export function collectAbideDiagnostics(shadow: ShadowProgram): AbideDiagnostic[] {
|
|
14
23
|
const { program, shadows, parseErrors, abidePaths } = shadow
|
|
24
|
+
const checker = program.getTypeChecker()
|
|
15
25
|
const diagnostics: AbideDiagnostic[] = []
|
|
16
26
|
for (const abidePath of abidePaths) {
|
|
17
27
|
const parseError = parseErrors.get(abidePath)
|
|
@@ -41,6 +51,15 @@ export function collectAbideDiagnostics(shadow: ShadowProgram): AbideDiagnostic[
|
|
|
41
51
|
if (sourceFile === undefined || mappings === undefined) {
|
|
42
52
|
continue
|
|
43
53
|
}
|
|
54
|
+
/* The template boundary: a diagnostic mapping at/after it is a template expression, so
|
|
55
|
+
eligible for the ADR-0032 bare-async-read suppression; anything before it is `<script>`
|
|
56
|
+
code, where a forgotten `await` must still surface. If the source can't be read, DON'T
|
|
57
|
+
fall back to 0 — that treats the whole file (including `<script>`) as template and would
|
|
58
|
+
silently suppress a genuine forgotten-await error. Use +Infinity so nothing is eligible
|
|
59
|
+
for suppression and every real diagnostic surfaces (fail toward reporting). */
|
|
60
|
+
const abideSource = ts.sys.readFile(abidePath)
|
|
61
|
+
const templateStart =
|
|
62
|
+
abideSource === undefined ? Number.POSITIVE_INFINITY : templateStartOffset(abideSource)
|
|
44
63
|
const raw = [
|
|
45
64
|
...program.getSyntacticDiagnostics(sourceFile),
|
|
46
65
|
...program.getSemanticDiagnostics(sourceFile),
|
|
@@ -57,6 +76,21 @@ export function collectAbideDiagnostics(shadow: ShadowProgram): AbideDiagnostic[
|
|
|
57
76
|
if (located === undefined) {
|
|
58
77
|
continue
|
|
59
78
|
}
|
|
79
|
+
/* Drop the diagnostics a bare async read (ADR-0032) provokes spuriously: the runtime
|
|
80
|
+
peeks the resolved value (`undefined` while pending), so a `?.` read of a real member
|
|
81
|
+
and an `{#if}` on the promise are valid — the raw-`Promise` shadow can't see that. */
|
|
82
|
+
if (
|
|
83
|
+
located.start >= templateStart &&
|
|
84
|
+
isSpuriousAsyncReadDiagnostic(
|
|
85
|
+
sourceFile,
|
|
86
|
+
checker,
|
|
87
|
+
diagnostic.code,
|
|
88
|
+
diagnostic.start,
|
|
89
|
+
diagnostic.length ?? 0,
|
|
90
|
+
)
|
|
91
|
+
) {
|
|
92
|
+
continue
|
|
93
|
+
}
|
|
60
94
|
diagnostics.push({
|
|
61
95
|
file: abidePath,
|
|
62
96
|
start: located.start,
|
|
@@ -65,6 +99,68 @@ export function collectAbideDiagnostics(shadow: ShadowProgram): AbideDiagnostic[
|
|
|
65
99
|
category: diagnostic.category,
|
|
66
100
|
})
|
|
67
101
|
}
|
|
102
|
+
/* Stage E parity (ADR-0019): the build front-end (`lowerAsyncInterpolations`) throws on a
|
|
103
|
+
promise/asyncIterable in a NON-content value position; mirror it here as a diagnostic so
|
|
104
|
+
`abide check`/the LSP surface the same error. The shadow already type-checks these
|
|
105
|
+
spans, so their offsets map through the same `mappings`; classify each against the
|
|
106
|
+
checker and emit an Error for any async value the guard rejects. */
|
|
107
|
+
collectValuePositionDiagnostics(abidePath, sourceFile, mappings, checker, diagnostics)
|
|
68
108
|
}
|
|
69
109
|
return diagnostics
|
|
70
110
|
}
|
|
111
|
+
|
|
112
|
+
/* Parses the component template, walks its value-position interpolations, and pushes a diagnostic
|
|
113
|
+
for any promise/asyncIterable the Stage E guard rejects. Classifies via the shadow: map the
|
|
114
|
+
expression's source offset into shadow coordinates, find its emitted expression node, read its
|
|
115
|
+
checker type. Fail-open — an unparseable template or unmappable span contributes nothing, so a
|
|
116
|
+
type hiccup degrades to no extra diagnostic instead of throwing. */
|
|
117
|
+
function collectValuePositionDiagnostics(
|
|
118
|
+
abidePath: string,
|
|
119
|
+
shadowFile: ts.SourceFile,
|
|
120
|
+
mappings: ShadowMapping[],
|
|
121
|
+
checker: ts.TypeChecker,
|
|
122
|
+
diagnostics: AbideDiagnostic[],
|
|
123
|
+
): void {
|
|
124
|
+
const source = ts.sys.readFile(abidePath)
|
|
125
|
+
if (source === undefined) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
/* The template starts just past the leading `<script>` — the SAME base `compileShadow` parses
|
|
129
|
+
from, so each interpolation's `loc` lines up with the shadow's source→shadow `mappings`. */
|
|
130
|
+
const templateStart = templateStartOffset(source)
|
|
131
|
+
/* The recovering core never throws — it returns best-effort `nodes` PLUS every parse
|
|
132
|
+
diagnostic. Surface each with the `file` + `category` the parser can't know, so the LSP
|
|
133
|
+
reports parse errors from mid-edit source instead of fail-opening on the first throw. */
|
|
134
|
+
const parsed = parseTemplateRecovering(source.slice(templateStart), templateStart)
|
|
135
|
+
const nodes = parsed.nodes
|
|
136
|
+
for (const parseDiagnostic of parsed.diagnostics) {
|
|
137
|
+
diagnostics.push({
|
|
138
|
+
file: abidePath,
|
|
139
|
+
start: parseDiagnostic.start,
|
|
140
|
+
length: parseDiagnostic.length,
|
|
141
|
+
message: parseDiagnostic.message,
|
|
142
|
+
category: ts.DiagnosticCategory.Error,
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
for (const interpolation of asyncValuePositionInterpolations(nodes)) {
|
|
146
|
+
const shadowOffset = sourceToShadowOffset(mappings, interpolation.loc)
|
|
147
|
+
if (shadowOffset === undefined) {
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
const node = nodeAtShadowOffset(shadowFile, shadowOffset, interpolation.code.length)
|
|
151
|
+
if (node === undefined) {
|
|
152
|
+
continue
|
|
153
|
+
}
|
|
154
|
+
const kind = classifyInterpolationType(checker.getTypeAtLocation(node), node, checker)
|
|
155
|
+
const message = asyncValuePositionError(kind, interpolation.position)
|
|
156
|
+
if (message !== undefined) {
|
|
157
|
+
diagnostics.push({
|
|
158
|
+
file: abidePath,
|
|
159
|
+
start: interpolation.loc,
|
|
160
|
+
length: interpolation.code.length,
|
|
161
|
+
message,
|
|
162
|
+
category: ts.DiagnosticCategory.Error,
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -2,6 +2,8 @@ import { analyzeComponent } from './analyzeComponent.ts'
|
|
|
2
2
|
import { generateBuild } from './generateBuild.ts'
|
|
3
3
|
import { hoistCells } from './hoistCells.ts'
|
|
4
4
|
import type { AnalyzedComponent } from './types/AnalyzedComponent.ts'
|
|
5
|
+
import type { InterpolationClassifier } from './types/InterpolationClassifier.ts'
|
|
6
|
+
import type { SeedTypeClassifier } from './types/SeedTypeClassifier.ts'
|
|
5
7
|
|
|
6
8
|
/*
|
|
7
9
|
Compiles a single-file abide component into the body of a client build function.
|
|
@@ -19,10 +21,24 @@ export function compileComponent(
|
|
|
19
21
|
source: string,
|
|
20
22
|
isLayout = false,
|
|
21
23
|
scopeSeed?: string,
|
|
22
|
-
analyzed
|
|
24
|
+
analyzed?: AnalyzedComponent,
|
|
25
|
+
classify?: InterpolationClassifier,
|
|
26
|
+
seedClassify?: SeedTypeClassifier,
|
|
23
27
|
): string {
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
/* `analyzed` is shared by `compileModule` (analyzed once, classifiers already applied);
|
|
29
|
+
a direct caller (tests) omits it and the front-end runs here — threading `classify` and
|
|
30
|
+
`seedClassify` so type-directed interpolation + cell lowering happen on this path too. */
|
|
31
|
+
const resolved = analyzed ?? analyzeComponent(source, scopeSeed, classify, seedClassify)
|
|
32
|
+
const { script, stateNames, derivedNames, computedNames, cellReadNames, nodes } = resolved
|
|
33
|
+
const build = generateBuild(
|
|
34
|
+
nodes,
|
|
35
|
+
'host',
|
|
36
|
+
stateNames,
|
|
37
|
+
derivedNames,
|
|
38
|
+
computedNames,
|
|
39
|
+
isLayout,
|
|
40
|
+
cellReadNames,
|
|
41
|
+
)
|
|
26
42
|
/* The scoped CSS is bundled into the entry stylesheet (see `abideUiPlugin`), not
|
|
27
43
|
injected at runtime; the build only needs the `data-a-…` scope attributes on
|
|
28
44
|
elements, which `generateBuild` reads from each node's annotated `scopes`. */
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import ts from 'typescript'
|
|
2
2
|
import { ABIDE_PACKAGE_NAME } from '../../shared/ABIDE_PACKAGE_NAME.ts'
|
|
3
3
|
import { analyzeComponent } from './analyzeComponent.ts'
|
|
4
|
-
import { assertRuntimeHelpersBound } from './assertRuntimeHelpersBound.ts'
|
|
5
4
|
import { assertTranspiles } from './assertTranspiles.ts'
|
|
6
5
|
import { compileComponent } from './compileComponent.ts'
|
|
7
6
|
import { compileSSR } from './compileSSR.ts'
|
|
8
7
|
import type { AnalyzedComponent } from './types/AnalyzedComponent.ts'
|
|
8
|
+
import type { InterpolationClassifier } from './types/InterpolationClassifier.ts'
|
|
9
|
+
import type { SeedTypeClassifier } from './types/SeedTypeClassifier.ts'
|
|
9
10
|
import { UI_RUNTIME_IMPORTS } from './UI_RUNTIME_IMPORTS.ts'
|
|
10
11
|
|
|
11
12
|
/*
|
|
@@ -26,52 +27,34 @@ what the `.abide` bundler loader emits.
|
|
|
26
27
|
*/
|
|
27
28
|
export function compileModule(
|
|
28
29
|
source: string,
|
|
29
|
-
options: {
|
|
30
|
+
options: {
|
|
31
|
+
isLayout?: boolean
|
|
32
|
+
moduleId?: string
|
|
33
|
+
/* Type-directed interpolation lowering (ADR-0019): the warm shadow classifier the
|
|
34
|
+
bundler plugin builds per `.abide`. Optional and fail-open — absent, the module
|
|
35
|
+
compiles exactly as before (every interpolation binds as a plain value). */
|
|
36
|
+
classify?: InterpolationClassifier
|
|
37
|
+
/* Type-directed cell lowering (ADR-0023): the seed classifier the plugin builds over
|
|
38
|
+
the SAME warm shadow program. Optional and fail-open — absent, a no-marker
|
|
39
|
+
`computed(seed)` routes by the `isBareCallComputed` syntax heuristic (today's behavior). */
|
|
40
|
+
seedClassify?: SeedTypeClassifier
|
|
41
|
+
} = {},
|
|
30
42
|
): { code: string; styles: AnalyzedComponent['styles'] } {
|
|
31
43
|
const isLayout = options.isLayout ?? false
|
|
32
44
|
/* Run the shared front-end once and feed it to both back-ends — the analysis is
|
|
33
45
|
pure over (source, moduleId), so the client and SSR builds reuse one parse
|
|
34
46
|
instead of re-running it. `imports` (hoisted child-component imports) and the
|
|
35
|
-
per-element scopes both come from this single pass.
|
|
36
|
-
|
|
47
|
+
per-element scopes both come from this single pass. The classifier (when present)
|
|
48
|
+
lowers promise-typed interpolations here, so both back-ends see one lowered tree. */
|
|
49
|
+
const analyzed = analyzeComponent(
|
|
50
|
+
source,
|
|
51
|
+
options.moduleId,
|
|
52
|
+
options.classify,
|
|
53
|
+
options.seedClassify,
|
|
54
|
+
)
|
|
37
55
|
const userImports = analyzed.imports
|
|
38
56
|
const body = indent(compileComponent(source, isLayout, options.moduleId, analyzed))
|
|
39
57
|
|
|
40
|
-
/* Hot module (dev component HMR): the same client build, but its runtime comes
|
|
41
|
-
from the live bundle via `window.__abide` — so it shares the one reactive graph
|
|
42
|
-
and instance registry, not fresh copies — and on load it hands the new factory
|
|
43
|
-
to `hotReplace`, which disposes + re-runs every live instance in place. No SSR /
|
|
44
|
-
hydrate / export: it is imported only to replace, never mounted fresh. Supports
|
|
45
|
-
leaf components today; one importing children falls back to a reload (the dev
|
|
46
|
-
layer decides what to hot-swap). */
|
|
47
|
-
if (options.hot) {
|
|
48
|
-
/* Bridge keys are the bare source names; bind each to its emitted local (`$$`
|
|
49
|
-
alias when set), so the hot body's `$$mountChild(...)` resolves. */
|
|
50
|
-
const names = UI_RUNTIME_IMPORTS.map((entry) =>
|
|
51
|
-
entry.alias === undefined || entry.alias === entry.name
|
|
52
|
-
? entry.name
|
|
53
|
-
: `${entry.name}: ${entry.alias}`,
|
|
54
|
-
).join(', ')
|
|
55
|
-
const id = JSON.stringify(options.moduleId)
|
|
56
|
-
/* Hot mode never imports the scoped CSS (it reuses the live bundle's sheet), so
|
|
57
|
-
styles are empty here regardless of the analyzed blocks. */
|
|
58
|
-
return {
|
|
59
|
-
code: `const { ${names}, hotReplace } = window.__abide
|
|
60
|
-
${userImports}
|
|
61
|
-
function build(host, $props) {
|
|
62
|
-
${body}
|
|
63
|
-
}
|
|
64
|
-
function component(host, $props) {
|
|
65
|
-
return $$mount(host, build, $props)
|
|
66
|
-
}
|
|
67
|
-
component.build = build
|
|
68
|
-
component.__abideId = ${id}
|
|
69
|
-
if (!hotReplace(${id}, component)) location.reload()
|
|
70
|
-
`,
|
|
71
|
-
styles: [],
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
58
|
const ssrBody = indent(compileSSR(source, isLayout, options.moduleId, analyzed))
|
|
76
59
|
const moduleBody = `function build(host, $props) {
|
|
77
60
|
${body}
|
|
@@ -95,7 +78,7 @@ component.hydrate = hydrateInto
|
|
|
95
78
|
/* The bare build, so a parent can range-mount this as a nested child (no wrapper). */
|
|
96
79
|
component.build = build
|
|
97
80
|
component.hydratable = ${analyzed.hydratable}
|
|
98
|
-
|
|
81
|
+
`
|
|
99
82
|
/* Per-component dead-import elimination: emit only the runtime helpers this module
|
|
100
83
|
references. A component using no `each`/`await`/`html` shouldn't drag those modules
|
|
101
84
|
into its chunk, and the package isn't globally side-effect-free (the dev/runtime
|
|
@@ -107,13 +90,10 @@ ${options.moduleId === undefined ? '' : `component.__abideId = ${JSON.stringify(
|
|
|
107
90
|
string/comment/HTML literal (e.g. an `on`-attribute in static markup) no longer
|
|
108
91
|
forces a spurious import, so no per-surface scoping is needed: a client-only helper
|
|
109
92
|
simply doesn't appear as an identifier in the SSR body. */
|
|
110
|
-
/* Parse the generated bodies ONCE and feed the
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
(`importedHelpers`), which is exactly what it would have read from the prepended imports
|
|
115
|
-
had it re-parsed the whole module. `setParentNodes` is required by the backstop's
|
|
116
|
-
`getStart`/line lookups. */
|
|
93
|
+
/* Parse the generated bodies ONCE and feed the tree to the dead-import filter
|
|
94
|
+
(`collectIdentifiers`) and the reactive-import backstop below. The import block isn't in
|
|
95
|
+
this tree yet — it is derived from the filter's result. `setParentNodes` lets
|
|
96
|
+
`collectValueReferences` distinguish a value use from a property name. */
|
|
117
97
|
const bodySource = ts.createSourceFile(
|
|
118
98
|
'module.ts',
|
|
119
99
|
`${userImports}\n${moduleBody}`,
|
|
@@ -161,17 +141,6 @@ ${moduleBody}`
|
|
|
161
141
|
template shape no test exercises) otherwise ships as a broken bundle; this surfaces
|
|
162
142
|
it as a located compile error for every component. */
|
|
163
143
|
assertTranspiles(module, 'component module generation')
|
|
164
|
-
/* `assertTranspiles` only proves the output PARSES — a call to an un-imported helper is
|
|
165
|
-
valid syntax, so it slips through. This second guard proves the output is BOUND: every
|
|
166
|
-
runtime helper it calls is actually imported (an independent check of the dead-import
|
|
167
|
-
filter above), turning a runtime `ReferenceError` into a located compile error. It walks
|
|
168
|
-
the SAME tree the filter just parsed, with the kept helper imports supplied as the bound
|
|
169
|
-
set the prepended import block provides. */
|
|
170
|
-
assertRuntimeHelpersBound(
|
|
171
|
-
bodySource,
|
|
172
|
-
new Set(keptImports.map((entry) => entry.alias ?? entry.name)),
|
|
173
|
-
'component module generation',
|
|
174
|
-
)
|
|
175
144
|
return { code: module, styles: analyzed.styles }
|
|
176
145
|
}
|
|
177
146
|
|
|
@@ -2,6 +2,8 @@ import { analyzeComponent } from './analyzeComponent.ts'
|
|
|
2
2
|
import { generateSSR } from './generateSSR.ts'
|
|
3
3
|
import { SSR_ESCAPE } from './SSR_ESCAPE.ts'
|
|
4
4
|
import type { AnalyzedComponent } from './types/AnalyzedComponent.ts'
|
|
5
|
+
import type { InterpolationClassifier } from './types/InterpolationClassifier.ts'
|
|
6
|
+
import type { SeedTypeClassifier } from './types/SeedTypeClassifier.ts'
|
|
5
7
|
|
|
6
8
|
/*
|
|
7
9
|
Compiles a component into the body of a server render function. Runs the shared
|
|
@@ -18,12 +20,12 @@ Effects are stripped — they are client lifecycle and emit no HTML, so the serv
|
|
|
18
20
|
render is a snapshot of the markup before any effect runs.
|
|
19
21
|
|
|
20
22
|
Defines `$$model` via the lowered script; the reactive scope is entered via `$$enterScope`
|
|
21
|
-
and exited in a `finally` block. The block-id counter is
|
|
22
|
-
|
|
23
|
-
`await` block
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
when a caller (a test, a top-level render) omits it.
|
|
23
|
+
and exited in a `finally` block. The block-id counter is the request-local `$ctx` — a
|
|
24
|
+
per-render-path `Map` (ADR-0037), threaded into child renders — not a module global. Each
|
|
25
|
+
`await`/`try` block draws `$$blockId($ctx)` = `${render-path}:${n}`, counting per path in
|
|
26
|
+
document order; namespacing by path (rather than one flat counter) keeps ids congruent with
|
|
27
|
+
the client even when sibling child renders run concurrently, and isolates concurrent requests.
|
|
28
|
+
`$ctx` defaults to a fresh `Map` when a caller (a test, a top-level render) omits it.
|
|
27
29
|
|
|
28
30
|
The body is wrapped in an ASYNC IIFE (returns `Promise<SsrRender>`) ONLY when it contains
|
|
29
31
|
an inline `await` — a blocking `{#await … then}` block, a child-component render, a `<slot>`
|
|
@@ -43,17 +45,54 @@ export function compileSSR(
|
|
|
43
45
|
source: string,
|
|
44
46
|
isLayout = false,
|
|
45
47
|
scopeSeed?: string,
|
|
46
|
-
analyzed
|
|
48
|
+
analyzed?: AnalyzedComponent,
|
|
49
|
+
classify?: InterpolationClassifier,
|
|
50
|
+
seedClassify?: SeedTypeClassifier,
|
|
47
51
|
): string {
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
/* `analyzed` is shared by `compileModule` (analyzed once, classifiers already applied);
|
|
53
|
+
a direct caller (tests) omits it and the front-end runs here — threading `classify` and
|
|
54
|
+
`seedClassify` so type-directed interpolation + cell lowering happen on this path too. */
|
|
55
|
+
const resolved = analyzed ?? analyzeComponent(source, scopeSeed, classify, seedClassify)
|
|
56
|
+
const {
|
|
57
|
+
ssrScript: lowered,
|
|
58
|
+
stateNames,
|
|
59
|
+
derivedNames,
|
|
60
|
+
computedNames,
|
|
61
|
+
cellReadNames,
|
|
62
|
+
nodes,
|
|
63
|
+
} = resolved
|
|
64
|
+
const {
|
|
65
|
+
body: ssr,
|
|
66
|
+
flightDecls,
|
|
67
|
+
hasStagedChildren,
|
|
68
|
+
} = generateSSR(nodes, stateNames, derivedNames, computedNames, isLayout, cellReadNames)
|
|
69
|
+
/* ADR-0039: a component with hoistable children declares `$childSlots` (the body walk reserves an
|
|
70
|
+
output slot per child) and, after the walk, awaits `$$finalizeStreamedChildren` — which fills
|
|
71
|
+
each slot inline (settled child, byte-identical to the old inline await) or with a streaming
|
|
72
|
+
boundary (still-pending child). Empty for a component with no hoistable child, which stays
|
|
73
|
+
synchronous. */
|
|
74
|
+
const childSlotsDecl = hasStagedChildren ? 'const $childSlots = [];\n' : ''
|
|
75
|
+
const finalizeChildren = hasStagedChildren
|
|
76
|
+
? 'await $$finalizeStreamedChildren($childSlots, $awaits, $resume);\n'
|
|
77
|
+
: ''
|
|
78
|
+
/* The Tier-2 await-barrier (ADR-0019): between the lowered cell declarations and the
|
|
79
|
+
template, drain + await every async cell's in-flight promise so the template's
|
|
80
|
+
`$$readCell(name)` peeks the RESOLVED value and it bakes into the first-pass HTML —
|
|
81
|
+
single render pass, no client refetch. Emitted whenever the component declares a cell
|
|
82
|
+
(`cellReadNames`: every `linked` / async or bare-call `computed`); the barrier only
|
|
83
|
+
awaits promises a cell actually registered server-side (a sync/stream cell registers
|
|
84
|
+
none), so it is a cheap no-op for a component whose cells all settled synchronously. */
|
|
85
|
+
const barrier = cellReadNames.size > 0 ? 'await $$settleAsyncCells();\n' : ''
|
|
50
86
|
/* No `<style>` in the markup — the scoped CSS is bundled into the entry stylesheet
|
|
51
87
|
the shell links (see `abideUiPlugin`), so SSR output is styled by that sheet. The
|
|
52
88
|
elements still carry their `data-a-…` scopes via `generateSSR`. */
|
|
53
89
|
/* `typeof model` guards a component with no reactive state (a pure-async or
|
|
54
90
|
static component declares no `model`); its snapshot is then empty. */
|
|
91
|
+
/* ADR-0034 flight declarations sit AFTER the lowered script (so their promises can read the
|
|
92
|
+
component's signals) and BEFORE the barrier (so a hoisted flight is already in-flight while
|
|
93
|
+
the barrier awaits any unrelated blocking cell). Empty when nothing hoisted. */
|
|
55
94
|
const body =
|
|
56
|
-
`const $scope = $$enterScope();\ntry {\n${lowered}\n${SSR_ESCAPE}\nconst $out = [];\nconst $awaits = [];\
|
|
95
|
+
`const $scope = $$enterScope();\ntry {\n${lowered}\n${flightDecls}${SSR_ESCAPE}\nconst $out = [];\nconst $awaits = [];\n${childSlotsDecl}const $resume = {};\n${barrier}${ssr}${finalizeChildren}` +
|
|
57
96
|
`return { html: $out.join(''), state: (typeof $$model !== 'undefined' ? $$model.snapshot() : {}), awaits: $awaits, resume: $resume };\n` +
|
|
58
97
|
`} finally { $$exitScope($scope); }`
|
|
59
98
|
/* An inline `await` — a blocking await block, a child render, a slot read, or a
|
|
@@ -63,6 +102,6 @@ export function compileSSR(
|
|
|
63
102
|
top-level `await` in a non-async function (a SyntaxError). `(?!:)` excludes the
|
|
64
103
|
`<!--abide:await:N-->` boundary-marker strings; `\b` excludes `$awaits`. A false
|
|
65
104
|
positive (the token in author text) only costs a needless async wrapper, never a crash. */
|
|
66
|
-
const needsAsync = /\bawait\b(?!:)/.test(`${lowered}${ssr}`)
|
|
67
|
-
return `var $ctx = $ctx ||
|
|
105
|
+
const needsAsync = hasStagedChildren || /\bawait\b(?!:)/.test(`${lowered}${ssr}${barrier}`)
|
|
106
|
+
return `var $ctx = $ctx || new Map();\n${needsAsync ? `return (async () => {\n${body}\n})();` : body}`
|
|
68
107
|
}
|