@abide/abide 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +70 -52
- package/CHANGELOG.md +177 -0
- package/README.md +12 -7
- 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
|
@@ -3,7 +3,7 @@ import type { effect } from '../effect.ts'
|
|
|
3
3
|
import type { linked } from '../linked.ts'
|
|
4
4
|
import type { Patch } from '../runtime/types/Patch.ts'
|
|
5
5
|
import type { state } from '../state.ts'
|
|
6
|
-
import type {
|
|
6
|
+
import type { trackedComputed } from '../trackedComputed.ts'
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
9
|
A lexical scope: the unit that owns a region's reactive data, its lifetime, and
|
|
@@ -14,21 +14,14 @@ surface is the imported `state`/`state.linked`/`state.computed`/`effect` (see
|
|
|
14
14
|
scope (`$$scope().derive`/`.linked`/`.effect`, `state.share`/`.shared` → `share`/
|
|
15
15
|
`shared`). The data surface MIRRORS `Doc` (read/replace/add/remove/derive/apply/
|
|
16
16
|
snapshot) so the compiler can target a scope as a component's data binding directly;
|
|
17
|
-
it
|
|
17
|
+
it passes values down the tree as context (`share`/`shared`).
|
|
18
18
|
|
|
19
|
-
The reactive primitives
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Capabilities route where the scope's changes go: `record()` to an undo journal,
|
|
23
|
-
`persist()` to durable storage, `broadcast()` to peers — declared once, then `undo`/
|
|
24
|
-
`redo` act on a recorded scope. The `history`/`persist`/`sync` helpers it composes are
|
|
25
|
-
internal.
|
|
19
|
+
The reactive primitives remain on this internal shape because the lowered runtime calls
|
|
20
|
+
them (`$$scope().linked(...)`) — they are withdrawn from the AUTHOR-facing public surface
|
|
21
|
+
(docs/examples), not the runtime object.
|
|
26
22
|
*/
|
|
27
23
|
export type Scope = {
|
|
28
24
|
readonly id: string
|
|
29
|
-
/* Dev-only display name (the host component/element it mounted into) for the
|
|
30
|
-
inspector's Reactive tab; undefined for SSR/detached/child scopes. */
|
|
31
|
-
readonly label?: string
|
|
32
25
|
readonly parent: Scope | undefined
|
|
33
26
|
/* data — mirrors Doc */
|
|
34
27
|
read: <T>(path: string) => T
|
|
@@ -54,15 +47,15 @@ export type Scope = {
|
|
|
54
47
|
state: typeof state
|
|
55
48
|
linked: typeof linked
|
|
56
49
|
computed: typeof computed
|
|
50
|
+
/* The eager stream-classifying read-only computed a bare-call `computed(getStream())`
|
|
51
|
+
lowers to — auto-tracks a stream/promise producer, falls back to a lazy computed. */
|
|
52
|
+
trackedComputed: typeof trackedComputed
|
|
57
53
|
effect: typeof effect
|
|
58
54
|
/* Adopts a teardown into this scope's lifetime — the build's reactivity stopper
|
|
59
55
|
(effects/listeners), run first on `dispose` (before children, before capabilities).
|
|
60
56
|
Internal: the mount core registers the build's disposer here so a component has ONE
|
|
61
57
|
teardown (`dispose`) rather than a separate stop + dispose composed at every site. */
|
|
62
58
|
own: (dispose: () => void) => void
|
|
63
|
-
/* tree */
|
|
64
|
-
child: (initial?: unknown) => Scope
|
|
65
|
-
root: () => Scope
|
|
66
59
|
/* context — values shared DOWN the tree (not in the reactive doc, which doesn't
|
|
67
60
|
inherit): `share` puts a named value on this scope; `shared` reads the closest
|
|
68
61
|
ancestor (self included) that has the key, undefined if none. The value is held
|
|
@@ -70,15 +63,6 @@ export type Scope = {
|
|
|
70
63
|
plain object snapshot. */
|
|
71
64
|
share: (key: string, value: unknown) => void
|
|
72
65
|
shared: <T>(key: string) => T | undefined
|
|
73
|
-
/* capabilities — enable where the scope's changes go */
|
|
74
|
-
record: (options?: { limit?: number }) => void
|
|
75
|
-
persist: (key?: string) => void
|
|
76
|
-
broadcast: (transport: SyncTransport) => void
|
|
77
|
-
/* undo/redo — act on a recorded scope */
|
|
78
|
-
undo: () => void
|
|
79
|
-
redo: () => void
|
|
80
|
-
canUndo: () => boolean
|
|
81
|
-
canRedo: () => boolean
|
|
82
66
|
/* lifetime */
|
|
83
67
|
dispose: () => void
|
|
84
68
|
}
|
package/src/lib/ui/watch.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cache } from '../shared/cache.ts'
|
|
2
2
|
import { REMOTE_FUNCTION } from '../shared/REMOTE_FUNCTION.ts'
|
|
3
3
|
import type { CacheOnContext } from '../shared/types/CacheOnContext.ts'
|
|
4
|
+
import type { NamedAsyncIterable } from '../shared/types/NamedAsyncIterable.ts'
|
|
4
5
|
import type { RemoteFunction } from '../shared/types/RemoteFunction.ts'
|
|
5
|
-
import type { Subscribable } from '../shared/types/Subscribable.ts'
|
|
6
6
|
import { effect } from './effect.ts'
|
|
7
7
|
import { generationGuard } from './runtime/generationGuard.ts'
|
|
8
8
|
import type { EffectResult } from './runtime/types/EffectResult.ts'
|
|
@@ -40,7 +40,7 @@ export function watch(
|
|
|
40
40
|
handler: (values: unknown[]) => void,
|
|
41
41
|
): () => void
|
|
42
42
|
export function watch<Frame>(
|
|
43
|
-
source:
|
|
43
|
+
source: NamedAsyncIterable<Frame>,
|
|
44
44
|
handler: (frame: Frame, context: CacheOnContext) => void | Promise<void>,
|
|
45
45
|
): () => void
|
|
46
46
|
export function watch<Args, Return>(
|
|
@@ -74,7 +74,7 @@ export function watch(
|
|
|
74
74
|
existing cache.on loop is the single implementation this branch delegates to. */
|
|
75
75
|
if (isSubscribable(source)) {
|
|
76
76
|
return cache.on(
|
|
77
|
-
source as
|
|
77
|
+
source as NamedAsyncIterable<unknown>,
|
|
78
78
|
handler as (frame: unknown, context: CacheOnContext) => void | Promise<void>,
|
|
79
79
|
)
|
|
80
80
|
}
|
package/src/serverEntry.ts
CHANGED
|
@@ -33,8 +33,11 @@ import { cacheStoreSlot } from './lib/shared/cacheStoreSlot.ts'
|
|
|
33
33
|
import { createCacheStore } from './lib/shared/createCacheStore.ts'
|
|
34
34
|
import { loadEnvFromDataDir } from './lib/shared/loadEnvFromDataDir.ts'
|
|
35
35
|
import { pageSlot } from './lib/shared/pageSlot.ts'
|
|
36
|
+
import { pendingAsyncCellsSlot } from './lib/shared/pendingAsyncCellsSlot.ts'
|
|
37
|
+
import { resolvedCellsSlot } from './lib/shared/resolvedCellsSlot.ts'
|
|
36
38
|
import { runningAsStandaloneBinary } from './lib/shared/runningAsStandaloneBinary.ts'
|
|
37
39
|
import { sharedCacheStoreSlot } from './lib/shared/sharedCacheStoreSlot.ts'
|
|
40
|
+
import { streamedCellsSlot } from './lib/shared/streamedCellsSlot.ts'
|
|
38
41
|
|
|
39
42
|
/*
|
|
40
43
|
Resolve config into process.env before anything reads it (createServer reads
|
|
@@ -76,6 +79,17 @@ sharedCacheStoreSlot.resolver = () => sharedCacheStore
|
|
|
76
79
|
|
|
77
80
|
cacheStoreSlot.resolver = () => requestContext.getStore()?.cache ?? sharedCacheStore
|
|
78
81
|
|
|
82
|
+
/* One process-wide fallback list for reads with no request in flight (boot/cron/socket) —
|
|
83
|
+
real requests each carry their own `pendingAsyncCells`, so the SSR barrier drains a
|
|
84
|
+
per-request list and concurrent renders never cross-contaminate. */
|
|
85
|
+
const sharedPendingAsyncCells = { promises: [] }
|
|
86
|
+
pendingAsyncCellsSlot.resolver = () =>
|
|
87
|
+
requestContext.getStore()?.pendingAsyncCells ?? sharedPendingAsyncCells
|
|
88
|
+
const sharedResolvedCells = { entries: [] }
|
|
89
|
+
resolvedCellsSlot.resolver = () => requestContext.getStore()?.resolvedCells ?? sharedResolvedCells
|
|
90
|
+
const sharedStreamedCells = { entries: [] }
|
|
91
|
+
streamedCellsSlot.resolver = () => requestContext.getStore()?.streamedCells ?? sharedStreamedCells
|
|
92
|
+
|
|
79
93
|
pageSlot.resolver = resolvePageSnapshot
|
|
80
94
|
|
|
81
95
|
await createServer({
|
|
@@ -6,17 +6,18 @@ the HTTP method. The bundler swaps the runtime per build target: direct call on
|
|
|
6
6
|
the server, fetch over the network on the client.
|
|
7
7
|
|
|
8
8
|
Args (what the caller passes in) come from the handler's parameter type —
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
decoding) is inferred from the handler's return type via the
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
annotate the parameter and the body infers; a typed generic on the helper is a
|
|
10
|
+
compile error. Return (what the caller receives after Content-Type-driven
|
|
11
|
+
decoding) is inferred from the handler's return type via the `TypedResponse<T>`
|
|
12
|
+
brand on `json`/`error`/`redirect`/`jsonl`/`sse`, so plain
|
|
13
|
+
`GET(() => json({...}))` already types end-to-end.
|
|
14
14
|
|
|
15
|
-
For inbound validation pass a Standard Schema
|
|
16
|
-
second argument: `GET(fn, {
|
|
17
|
-
schema's output type and the server replies with 422 on validation
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
For inbound validation pass a Standard Schema under `schemas.input` in the
|
|
16
|
+
second argument: `GET(fn, { schemas: { input } })`. Args then infers from the
|
|
17
|
+
schema's output type and the server replies with 422 on validation failure. An
|
|
18
|
+
optional `schemas.output` describes the success body for the OpenAPI 200
|
|
19
|
+
response and the MCP tool output; without one the handler's return type is
|
|
20
|
+
projected to JSON Schema.
|
|
20
21
|
|
|
21
22
|
`json(...)` from `abide/server/json` is a thin wrapper over `Response.json`
|
|
22
23
|
that defaults `Cache-Control: no-store`, since intermediary caches shouldn't
|
|
@@ -24,10 +25,11 @@ memoise rpc replies (the framework's per-request cache handles in-process
|
|
|
24
25
|
dedupe). Other helpers are siblings, one per file: `abide/server/error`,
|
|
25
26
|
`abide/server/redirect`, `abide/server/sse`, `abide/server/jsonl`.
|
|
26
27
|
|
|
27
|
-
Every rpc value also exposes `.raw(args?)` (returns the underlying
|
|
28
|
+
Every rpc value also exposes `.raw(args?, init?)` (returns the underlying
|
|
28
29
|
`Response`) for callers that need headers or status. A streaming rpc — a
|
|
29
|
-
jsonl/sse handler — returns a `
|
|
30
|
-
call (`fn(args)`); iterate it with `for await` or react to it with
|
|
30
|
+
jsonl/sse handler — returns a `NamedAsyncIterable` over the frames from its bare
|
|
31
|
+
call (`fn(args)`); iterate it with `for await` or react to it with
|
|
32
|
+
`watch(fn(args), frame => …)`.
|
|
31
33
|
*/
|
|
32
34
|
|
|
33
35
|
import { GET } from '@abide/abide/server/GET'
|
|
@@ -5,7 +5,7 @@ same wiring as `abide start`, no fixtures) and hands back the whole surface:
|
|
|
5
5
|
app.fetch(path) — pages and raw HTTP, origin + mount base resolved
|
|
6
6
|
app.rpc.<name>(args) — RPCs over the real pipeline (CSRF, cookies, base),
|
|
7
7
|
typed and decoded; .raw(args) for the Response
|
|
8
|
-
app.sockets.<name> — a live Socket: iterate it (for await), .peek(), .
|
|
8
|
+
app.sockets.<name> — a live Socket: iterate it (for await), .peek(), .publish(m)
|
|
9
9
|
app.health() — the /__abide/health payload
|
|
10
10
|
|
|
11
11
|
`app.rpc` / `app.sockets` are typed from your own RPCs and sockets — generated
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path'
|
|
2
|
-
import { NO_STORE } from '../../shared/CACHE_CONTROL_VALUES.ts'
|
|
3
|
-
import { isLayoutFile } from '../../shared/isLayoutFile.ts'
|
|
4
|
-
import { compileModule } from '../../ui/compile/compileModule.ts'
|
|
5
|
-
|
|
6
|
-
// Reused across requests — strips the embedded author TypeScript to browser JS.
|
|
7
|
-
const TRANSPILER = new Bun.Transpiler({ loader: 'ts' })
|
|
8
|
-
|
|
9
|
-
/*
|
|
10
|
-
Serves one edited `.abide`'s hot module (dev component HMR). Compiles it in hot
|
|
11
|
-
mode — runtime sourced from `window.__abide`, self-invoking `hotReplace` — and
|
|
12
|
-
transpiles the embedded author TypeScript to plain JS the browser can import
|
|
13
|
-
directly (the normal pipeline relies on the bundler's `ts` loader for this). The
|
|
14
|
-
browser imports this in place of a reload; on load it swaps the component's live
|
|
15
|
-
instances. The id is guarded as a project-relative `.abide` under cwd; a bad
|
|
16
|
-
module ID returns 400; a missing file 404s so the client falls back to a reload.
|
|
17
|
-
*/
|
|
18
|
-
export async function devHotModuleResponse(moduleId: string): Promise<Response> {
|
|
19
|
-
const root = process.cwd()
|
|
20
|
-
const path = resolve(root, moduleId)
|
|
21
|
-
if (!moduleId.endsWith('.abide') || !path.startsWith(`${root}/`)) {
|
|
22
|
-
return new Response('bad request', { status: 400 })
|
|
23
|
-
}
|
|
24
|
-
const source = await Bun.file(path)
|
|
25
|
-
.text()
|
|
26
|
-
.catch(() => undefined)
|
|
27
|
-
if (source === undefined) {
|
|
28
|
-
return new Response('not found', { status: 404 })
|
|
29
|
-
}
|
|
30
|
-
const { code } = compileModule(source, {
|
|
31
|
-
isLayout: isLayoutFile(moduleId),
|
|
32
|
-
moduleId,
|
|
33
|
-
hot: true,
|
|
34
|
-
})
|
|
35
|
-
return new Response(TRANSPILER.transformSync(code), {
|
|
36
|
-
headers: {
|
|
37
|
-
'Content-Type': 'application/javascript; charset=utf-8',
|
|
38
|
-
'Cache-Control': NO_STORE,
|
|
39
|
-
},
|
|
40
|
-
})
|
|
41
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Path prefix of the dev-only component hot-module endpoint (`/__abide/hot/<moduleId>`).
|
|
3
|
-
The browser imports `<prefix><moduleId>?v=<hash>` to fetch one edited component's
|
|
4
|
-
hot module instead of reloading. Shared so the server route (createServer) and the
|
|
5
|
-
live-reload client (DEV_RELOAD_CLIENT_SCRIPT) agree.
|
|
6
|
-
*/
|
|
7
|
-
export const DEV_HOT_PREFIX = '/__abide/hot/'
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
HTTP statuses that mean "the server didn't process this request" — the gateway /
|
|
3
|
-
availability family. A response with one of these is treated like a transport failure
|
|
4
|
-
by a durable RPC: the call still throws (the error framework is unchanged), and the
|
|
5
|
-
request is parked for replay on recovery. Everything else (4xx, 500, …) means the
|
|
6
|
-
server received and handled it — that flows to the error framework, never the outbox.
|
|
7
|
-
|
|
8
|
-
502 Bad Gateway · 503 Service Unavailable · 504 Gateway Timeout (abide's own client
|
|
9
|
-
timeout surfaces here too) · 520–527, 530 — Cloudflare/CDN origin-unreachable.
|
|
10
|
-
*/
|
|
11
|
-
export const UNREACHABLE_STATUSES: ReadonlySet<number> = new Set([
|
|
12
|
-
502, 503, 504, 520, 521, 522, 523, 524, 525, 526, 527, 530,
|
|
13
|
-
])
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { isReplayableMethod } from './isReplayableMethod.ts'
|
|
2
|
-
import type { CacheEntry } from './types/CacheEntry.ts'
|
|
3
|
-
|
|
4
|
-
/*
|
|
5
|
-
Whether a cache entry carries a wire request that can be replayed from a warm
|
|
6
|
-
snapshot — a replayable (GET-only) method, so the seed never re-fires a write or
|
|
7
|
-
loses a body. Producer entries (no request) and write methods fail it.
|
|
8
|
-
|
|
9
|
-
The request half of snapshot shippability, factored out so the two gates that
|
|
10
|
-
need it cannot drift: `snapshotShippable` composes it with `settled` for the
|
|
11
|
-
store-filter sites, and `snapshotEntryFromCache` calls it alone — its
|
|
12
|
-
streaming-drain caller hands it still-pending entries it then awaits, so it can't
|
|
13
|
-
require `settled` up front.
|
|
14
|
-
*/
|
|
15
|
-
export function hasReplayableRequest(entry: CacheEntry): boolean {
|
|
16
|
-
return entry.request !== undefined && isReplayableMethod(entry.request.method.toUpperCase())
|
|
17
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Set true only while the client adopts the server-rendered DOM (the hydration
|
|
3
|
-
render pass — see the router's hydrate branch and `hydrate`). Read by `peek`: the
|
|
4
|
-
server materializes no cache value (materializeRetained/cacheEntryFromSnapshot are
|
|
5
|
-
client-only), so server-side peek is uniformly undefined and the SSR render always
|
|
6
|
-
shows the fallback. A snapshot-seeded warm value surfacing DURING hydration would
|
|
7
|
-
diverge from that server text and corrupt the claimed text node, so peek withholds
|
|
8
|
-
it until the pass ends — `wakeHydrationPeeks` then re-runs the scope on the now-
|
|
9
|
-
congruent value. A plain boolean, save/restore-nested so a child hydrate can't clear
|
|
10
|
-
an outer pass early; false on the server (no hydration) and after boot.
|
|
11
|
-
*/
|
|
12
|
-
export const hydratingSlot: { active: boolean } = { active: false }
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Internal slot the browser outbox registry registers its prober into, so the
|
|
3
|
-
shared pending() probe can count parked durable-rpc writes without shared/
|
|
4
|
-
importing browser/. Mirrors tailProbeSlot. The prober reads the doc-backed
|
|
5
|
-
queue entries (reactive inside scope().computed() / scope().effect()) and reports whether any
|
|
6
|
-
undelivered entry matches the selector: a durable rpc selector (carries a
|
|
7
|
-
`url`) narrows to its own queue, the bare form spans every registered queue,
|
|
8
|
-
optional args narrow to one parked call by structural compare. Outbox state is
|
|
9
|
-
pending-only — a parked write has no value, so it never contributes to
|
|
10
|
-
refreshing(); probeRegistries reads this slot only on its `field === 'pending'`
|
|
11
|
-
branch, which is why the slot mirrors tailProbeSlot but reports a bare boolean
|
|
12
|
-
rather than a { pending, refreshing } pair. When no prober is registered (server
|
|
13
|
-
render, or no durable rpc was ever used) pending() sees no parked writes,
|
|
14
|
-
exactly as on the server where there are no client queues.
|
|
15
|
-
*/
|
|
16
|
-
export const outboxProbeSlot: {
|
|
17
|
-
probe: ((selector: unknown, args: unknown) => boolean) | undefined
|
|
18
|
-
} = {
|
|
19
|
-
probe: undefined,
|
|
20
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { OutboxEntry } from './OutboxEntry.ts'
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
The `.outbox` face on a durable RPC's client proxy: callable to read the reactive list
|
|
5
|
-
of undelivered entries (`rpc.outbox()`), with an awaitable `retry()` that drains the whole
|
|
6
|
-
queue and resolves when the replay settles. Server-side there is no client queue, so the
|
|
7
|
-
face is absent.
|
|
8
|
-
*/
|
|
9
|
-
export type Outbox<Args> = (() => OutboxEntry<Args>[]) & { retry: () => Promise<void> }
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/* The lifecycle status of a parked mutation: waiting to (re)send, or currently sending.
|
|
2
|
-
A write lives in the outbox ONLY while it can't reach the server; the instant the server
|
|
3
|
-
responds at all — a 2xx OR a real 4xx/500 — the entry leaves the queue, so there is no
|
|
4
|
-
terminal `error` state. Only the unreachable family (transport failure / 502/503/504/52x)
|
|
5
|
-
keeps it `queued`. */
|
|
6
|
-
export type OutboxStatus = 'queued' | 'sending'
|
|
7
|
-
|
|
8
|
-
/* One durable, replayable mutation in an RPC's outbox — parked because the original
|
|
9
|
-
call couldn't reach the server (transport failure, or a 502/503/504/52x). `controller`
|
|
10
|
-
is the entry's own abort handle (cancel = `controller.abort()`); `request` is the
|
|
11
|
-
synthesized, persisted Request the drain re-sends; `args` is the typed input (for
|
|
12
|
-
rendering); `error` is why it's parked (the `kind: 'queued'` HttpError from the
|
|
13
|
-
unreachable attempt); `retry()` kicks a FIFO drain. `settled` is the eventual outcome
|
|
14
|
-
of THIS write as if the original call had reached the server — it resolves with the
|
|
15
|
-
decoded result on delivery and rejects with the real HttpError on a server refusal (or
|
|
16
|
-
an AbortError on cancel). It may stay pending indefinitely if the write is never
|
|
17
|
-
replayed; reading it is what arms it (a never-read `settled` never rejects). */
|
|
18
|
-
export type OutboxEntry<Args> = {
|
|
19
|
-
id: string
|
|
20
|
-
controller: AbortController
|
|
21
|
-
request: Request
|
|
22
|
-
args: Args
|
|
23
|
-
status: OutboxStatus
|
|
24
|
-
error?: unknown
|
|
25
|
-
retry: () => Promise<void>
|
|
26
|
-
settled: Promise<unknown>
|
|
27
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Second-argument options for the smart bare rpc call (`getFoo(args, opts)`). The
|
|
3
|
-
call is cached/coalesced/reactive with SWR always on for replayable reads, so
|
|
4
|
-
these govern retention and the refetch clock — NOT transport. Per-call transport
|
|
5
|
-
options (signal/keepalive/priority/cache/headers) live on `.raw(args, init)`.
|
|
6
|
-
|
|
7
|
-
Fetch reads:
|
|
8
|
-
- `ttl` — retention/staleness in ms. Default: 0 on the server (coalesce-only —
|
|
9
|
-
the request is the atomic unit, nothing is retained past it), Infinity on the
|
|
10
|
-
client (retain until invalidate/refresh — the tab is the atomic unit). On the
|
|
11
|
-
client, N ms marks a staleness deadline: the retained value goes stale after N
|
|
12
|
-
ms and the next access triggers a background revalidation (stale stays visible,
|
|
13
|
-
`refreshing()` true); the display value is never dropped. On the server, N ms
|
|
14
|
-
is a plain expiry and only takes effect in the shared store (pair with `shared`).
|
|
15
|
-
- `tags` — free-form invalidation-group labels (see the selector grammar).
|
|
16
|
-
- `throttle` / `debounce` — rate-limit the background refetch clock (set one, not
|
|
17
|
-
both). Leading-edge-then-coalesce, or fire-after-quiet respectively.
|
|
18
|
-
- `shared` — opts the entry into the process-level store instead of the default
|
|
19
|
-
request-scoped one (server) — a store that outlives every request. It selects
|
|
20
|
-
the store only; it does NOT retain (pair it with `ttl` to memoise across
|
|
21
|
-
requests). The shared store is keyed by method+url+args, never by user, so do
|
|
22
|
-
not put per-user data in it — it would be served to other users. Omit `shared`
|
|
23
|
-
for per-request data. Write only `shared: true`; there is no `false` form. On
|
|
24
|
-
the client there is a single tab store, so the flag is a no-op there.
|
|
25
|
-
|
|
26
|
-
Streaming reads (jsonl/sse):
|
|
27
|
-
- `n` — how many retained frames to replay before going live.
|
|
28
|
-
*/
|
|
29
|
-
export type SmartReadOptions = {
|
|
30
|
-
ttl?: number
|
|
31
|
-
tags?: string[]
|
|
32
|
-
throttle?: number
|
|
33
|
-
debounce?: number
|
|
34
|
-
shared?: boolean
|
|
35
|
-
n?: number
|
|
36
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { cacheStores } from './cacheStores.ts'
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
Fired once when the outermost hydration pass ends (see the router's hydrate branch
|
|
5
|
-
and `hydrate`). During the pass `peek` withheld every snapshot-seeded warm value
|
|
6
|
-
for SSR congruence (see hydratingSlot); now that the pass is over those values are
|
|
7
|
-
congruent to show, so re-run the scopes that read them. A peek scope taps the exact
|
|
8
|
-
call key's lifecycle channel (peek's trackLifecycle), so marking every live entry's
|
|
9
|
-
key wakes them — cheap, one-time, and harmless for non-peek lifecycle readers (they
|
|
10
|
-
recompute the same value). Marks by key, not the bare store-wide channel, because a
|
|
11
|
-
peek(fn, args) scope taps the per-key prefix channel, which a keyless mark misses.
|
|
12
|
-
*/
|
|
13
|
-
export function wakeHydrationPeeks(): void {
|
|
14
|
-
const stores = cacheStores()
|
|
15
|
-
for (const store of stores) {
|
|
16
|
-
for (const key of store.entries.keys()) {
|
|
17
|
-
store.markLifecycle(key)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/* The `abide-` tag prefix on framework-owned custom elements (the router's
|
|
2
|
-
`abide-outlet`, the streaming `abide-resolve`/`abide-cache` fragments). `scopeLabel`
|
|
3
|
-
strips it to derive the bare name from a framework-owned host tag (e.g. `abide-resolve` → `resolve`). Child components no longer mount into
|
|
4
|
-
an `abide-<name>` wrapper — they build as marker ranges (see `mountRange`). */
|
|
5
|
-
export const COMPONENT_WRAPPER_PREFIX = 'abide-'
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/* The author-facing reactive primitive names (`state`, `state.linked`, `state.computed`,
|
|
2
|
-
and the destructuring `const {…} = props()`). The compiler no longer reads this —
|
|
3
|
-
recognition is import-resolved (see `resolveReactiveExport.ts`). It remains the canonical
|
|
4
|
-
inventory the docs surface-weighting tool enumerates (`scripts/surfaceWeight.ts`), so the
|
|
5
|
-
grammar's "primitives" bucket stays in sync with the language without hardcoding a list. */
|
|
6
|
-
export const REACTIVE_CALLEES: ReadonlySet<string> = new Set([
|
|
7
|
-
'state',
|
|
8
|
-
'linked',
|
|
9
|
-
'computed',
|
|
10
|
-
'props',
|
|
11
|
-
])
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript'
|
|
2
|
-
import { UI_RUNTIME_IMPORTS } from './UI_RUNTIME_IMPORTS.ts'
|
|
3
|
-
|
|
4
|
-
/*
|
|
5
|
-
Independent backstop on the per-component dead-import filter (`compileModule`). The filter
|
|
6
|
-
decides which runtime helpers to import by reading the generated output's identifiers; if it
|
|
7
|
-
ever undercounts — as a raw token scan once did, mis-reading the tail of a module after a
|
|
8
|
-
`${…}` template substitution — a helper gets CALLED but never imported, and the bundle throws
|
|
9
|
-
`ReferenceError` the instant `build()` runs. The router escalates that into a reload loop, so
|
|
10
|
-
the failure is both opaque and unrecoverable.
|
|
11
|
-
|
|
12
|
-
This re-derives the same question a DIFFERENT way (so it can't share the filter's blind spot):
|
|
13
|
-
walk the final module's AST, find every call whose callee is a bare runtime-helper identifier,
|
|
14
|
-
and require that name to be imported or locally bound. A helper name inside a string / template /
|
|
15
|
-
comment is not a `CallExpression` callee, so a docs component quoting framework code
|
|
16
|
-
(`mount(...)` in a snippet) never false-positives. Compile-time only; never on the hot path.
|
|
17
|
-
*/
|
|
18
|
-
/* `module` is either the source string (standalone use — parsed here) or the already-parsed
|
|
19
|
-
tree of the bodies WITHOUT the prepended import block (compile pipeline — shares the one
|
|
20
|
-
parse the dead-import filter made). In the latter case the import block's bindings aren't in
|
|
21
|
-
the tree, so `importedHelpers` supplies the helper names that block will bind. */
|
|
22
|
-
export function assertRuntimeHelpersBound(
|
|
23
|
-
module: string | ts.SourceFile,
|
|
24
|
-
importedHelpers: Set<string>,
|
|
25
|
-
context: string,
|
|
26
|
-
): void {
|
|
27
|
-
/* The EMITTED local names (the `$$` alias when set) — codegen calls those, and the
|
|
28
|
-
aliased import binds them, so the bound/called check must use the same form. */
|
|
29
|
-
const helperNames = new Set(UI_RUNTIME_IMPORTS.map((entry) => entry.alias ?? entry.name))
|
|
30
|
-
const source =
|
|
31
|
-
typeof module === 'string'
|
|
32
|
-
? ts.createSourceFile(
|
|
33
|
-
'module.ts',
|
|
34
|
-
module,
|
|
35
|
-
ts.ScriptTarget.Latest,
|
|
36
|
-
/* setParentNodes */ true,
|
|
37
|
-
)
|
|
38
|
-
: module
|
|
39
|
-
/* Names a bare call can resolve to: the import block's helper bindings (supplied when the
|
|
40
|
-
tree omits them) plus every import binding and declared name in the tree. Collected
|
|
41
|
-
generously (any identifier in a binding position) — over-approximating the bound set only
|
|
42
|
-
risks missing a defect, never raising a false alarm on valid output. */
|
|
43
|
-
const bound = new Set<string>(importedHelpers)
|
|
44
|
-
const calledHelpers: { name: string; position: number }[] = []
|
|
45
|
-
const visit = (node: ts.Node): void => {
|
|
46
|
-
if (
|
|
47
|
-
(ts.isVariableDeclaration(node) ||
|
|
48
|
-
ts.isFunctionDeclaration(node) ||
|
|
49
|
-
ts.isParameter(node) ||
|
|
50
|
-
ts.isBindingElement(node) ||
|
|
51
|
-
ts.isImportSpecifier(node) ||
|
|
52
|
-
ts.isImportClause(node) ||
|
|
53
|
-
ts.isNamespaceImport(node)) &&
|
|
54
|
-
node.name !== undefined &&
|
|
55
|
-
ts.isIdentifier(node.name)
|
|
56
|
-
) {
|
|
57
|
-
bound.add(node.name.text)
|
|
58
|
-
}
|
|
59
|
-
if (
|
|
60
|
-
ts.isCallExpression(node) &&
|
|
61
|
-
ts.isIdentifier(node.expression) &&
|
|
62
|
-
helperNames.has(node.expression.text)
|
|
63
|
-
) {
|
|
64
|
-
calledHelpers.push({
|
|
65
|
-
name: node.expression.text,
|
|
66
|
-
position: node.expression.getStart(source),
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
node.forEachChild(visit)
|
|
70
|
-
}
|
|
71
|
-
visit(source)
|
|
72
|
-
|
|
73
|
-
const unbound = calledHelpers.find((call) => !bound.has(call.name))
|
|
74
|
-
if (unbound !== undefined) {
|
|
75
|
-
const { line, character } = source.getLineAndCharacterOfPosition(unbound.position)
|
|
76
|
-
throw new Error(
|
|
77
|
-
`[abide] ${context} calls runtime helper \`${unbound.name}\` at line ${line + 1}:${character + 1} but never imports it — the dead-import filter dropped it. Please report this with the component source.\nOutput:\n${source.text}`,
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
}
|