@abide/abide 0.101.0 → 0.102.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/CHANGELOG.md +16 -0
- package/bin/abide.ts +223 -164
- package/docs/REGISTRY.md +726 -0
- package/docs/RULEBOOK.md +2753 -0
- package/docs/abide.md +12878 -0
- package/package.json +5 -3
- package/scaffold/AGENTS.md +31 -0
- package/scaffold/CLAUDE.md +1 -0
- package/scaffold/src/layout.abide +18 -0
- package/src/compiler/Lowering.ts +78 -9
- package/src/compiler/ShadowMap.ts +2 -2
- package/src/compiler/TypeSession.ts +262 -67
- package/src/compiler/argsSchemaOf.ts +1 -1
- package/src/compiler/checkApp.ts +43 -15
- package/src/compiler/checkedShadow.ts +39 -5
- package/src/compiler/classifyRead.ts +6 -4
- package/src/compiler/classifyTemplate.ts +1 -1
- package/src/compiler/compileApp.ts +433 -193
- package/src/compiler/compiledEntry.ts +43 -39
- package/src/compiler/componentGraph.ts +58 -71
- package/src/compiler/declaredExports.ts +24 -7
- package/src/compiler/emitClient.ts +141 -71
- package/src/compiler/emitComponent.ts +37 -8
- package/src/compiler/emitSource.ts +106 -13
- package/src/compiler/handlersUnder.ts +106 -59
- package/src/compiler/index.ts +7 -0
- package/src/compiler/mountsOf.ts +138 -0
- package/src/compiler/nearest.ts +14 -0
- package/src/compiler/parseAbide.ts +157 -20
- package/src/compiler/projectShadow.ts +213 -7
- package/src/compiler/reactiveTypes.ts +20 -7
- package/src/compiler/readSources.ts +15 -2
- package/src/compiler/readsIn.ts +61 -7
- package/src/compiler/renderMarkup.ts +3 -3
- package/src/compiler/scaffold.ts +30 -11
- package/src/compiler/serveLanguage.ts +125 -34
- package/src/compiler/sourceMapOf.ts +193 -0
- package/src/compiler/splitImports.ts +205 -83
- package/src/compiler/syncTypes.ts +32 -0
- package/src/compiler/tokenize.ts +14 -0
- package/src/compiler/writeDefaultProject.ts +1 -1
- package/src/compiler/writeTypes.ts +82 -0
- package/src/server/CLIENT_BUILD.ts +11 -13
- package/src/server/DEFAULT_PORT.ts +1 -1
- package/src/server/LAUNCHER_FILES.ts +9 -0
- package/src/server/MODULE_QUERIES.ts +18 -0
- package/src/server/TABLES.ts +7 -0
- package/src/server/VIRTUAL_DIRECTORY.ts +4 -5
- package/src/server/abideModules.ts +391 -0
- package/src/server/answerFailure.ts +16 -6
- package/src/server/answerRequest.ts +235 -106
- package/src/server/answerRpc.ts +102 -30
- package/src/server/answerSocket.ts +65 -20
- package/src/server/answerValue.ts +22 -9
- package/src/server/appDirectories.ts +1 -1
- package/src/server/appPlugins.ts +1 -1
- package/src/server/appTree.ts +179 -0
- package/src/server/argsFor.ts +2 -2
- package/src/server/assistant.ts +2 -2
- package/src/server/bridgeRelay.ts +6 -8
- package/src/server/claudeCode.ts +0 -6
- package/src/server/clientBuildOptions.ts +8 -3
- package/src/server/coerceArgs.ts +1 -1
- package/src/server/commands.ts +37 -37
- package/src/server/componentModules.d.ts +3 -1
- package/src/server/compressAnswer.ts +4 -4
- package/src/server/config.ts +25 -29
- package/src/server/configFields.ts +31 -25
- package/src/server/createApp.ts +59 -73
- package/src/server/devWorker.ts +114 -181
- package/src/server/executableName.ts +4 -0
- package/src/server/fenceServer.ts +37 -35
- package/src/server/generatedSurfaces.ts +99 -66
- package/src/server/hooks.ts +124 -52
- package/src/server/iconAccent.ts +191 -0
- package/src/server/index.ts +11 -7
- package/src/server/installSourceMaps.ts +88 -0
- package/src/server/launcherOptions.ts +34 -31
- package/src/server/launcherPage.ts +107 -64
- package/src/server/manifestOf.ts +16 -13
- package/src/server/namesUnder.ts +2 -2
- package/src/server/nativeMenu.ts +5 -5
- package/src/server/negotiateEncoding.ts +1 -1
- package/src/server/principal.ts +10 -5
- package/src/server/realOrAsGiven.ts +10 -0
- package/src/server/refuseAddressCollision.ts +21 -14
- package/src/server/remote.ts +49 -52
- package/src/server/render.ts +65 -94
- package/src/server/renderComponent.ts +5 -0
- package/src/server/reportHealth.ts +2 -2
- package/src/server/requestScope.ts +12 -1
- package/src/server/runBuild.ts +24 -0
- package/src/server/runCompiled.ts +5 -5
- package/src/server/runDesktop.ts +52 -27
- package/src/server/serveBuild.ts +43 -52
- package/src/server/serveDev.ts +73 -37
- package/src/server/shell.ts +7 -22
- package/src/server/sourceMappings.ts +139 -0
- package/src/server/surfaceOf.ts +18 -3
- package/src/server/testBuild.ts +1 -19
- package/src/server/withAbideSources.ts +117 -0
- package/src/shared/ADDRESSES.ts +7 -18
- package/src/shared/APP_META.ts +7 -0
- package/src/shared/CopyOptions.ts +1 -1
- package/src/shared/DEBUG_META.ts +1 -1
- package/src/shared/RESERVED_DIRECTORIES.ts +15 -0
- package/src/shared/cookies.ts +2 -2
- package/src/shared/csp.ts +1 -1
- package/src/shared/escapeText.ts +1 -1
- package/src/shared/filledPath.ts +85 -0
- package/src/shared/framing.ts +79 -6
- package/src/shared/headKeyOf.ts +2 -0
- package/src/shared/index.ts +1 -1
- package/src/shared/log.ts +27 -13
- package/src/shared/matchRoute.ts +23 -4
- package/src/shared/menuItem.ts +3 -3
- package/src/shared/reactive/Keyed.ts +2 -2
- package/src/shared/reactive/NotLanded.ts +1 -1
- package/src/shared/reactive/Reactive.ts +43 -43
- package/src/shared/reactive/argsContract.ts +4 -4
- package/src/shared/reactive/canonicalKey.ts +4 -4
- package/src/shared/reactive/chunksOfStream.ts +6 -0
- package/src/shared/reactive/index.ts +1 -1
- package/src/shared/reactive/recordWrites.ts +103 -5
- package/src/shared/reactive/structural.ts +1 -1
- package/src/shared/reactive/tracking.ts +1 -1
- package/src/shared/reactive/watch.ts +3 -3
- package/src/shared/refuse.ts +1 -1
- package/src/shared/routePattern.ts +82 -46
- package/src/shared/rpc.ts +37 -8
- package/src/shared/rpcRequest.ts +27 -3
- package/src/shared/url.ts +4 -44
- package/src/shared/writePath.ts +1 -1
- package/src/ui/LAYER_NAMES.ts +1 -1
- package/src/ui/List.ts +3 -3
- package/src/ui/MOUNTING_LEVEL.ts +18 -0
- package/src/ui/Mismatch.ts +1 -1
- package/src/ui/RawRun.ts +1 -1
- package/src/ui/Router.ts +38 -31
- package/src/ui/Scope.ts +1 -1
- package/src/ui/TryRegion.ts +2 -2
- package/src/ui/applyHead.ts +33 -0
- package/src/ui/index.ts +1 -1
- package/src/ui/menuBridge.ts +1 -1
- package/src/ui/moveNode.ts +1 -1
- package/src/ui/reconcile.ts +2 -2
- package/src/ui/reportMenu.ts +2 -2
- package/src/ui/routing.ts +2 -2
- package/src/ui/setAttribute.ts +1 -1
- package/src/ui/setText.ts +1 -1
- package/src/ui/socketWire.ts +9 -7
- package/src/ui/wire.ts +1 -1
- package/scaffold/src/server/app.ts +0 -6
- package/scaffold/src/shared/.gitkeep +0 -0
- package/scaffold/src/ui/app.html +0 -8
- package/src/server/componentImports.ts +0 -56
- /package/scaffold/src/{ui/pages/page.abide → page.abide} +0 -0
package/src/server/createApp.ts
CHANGED
|
@@ -10,19 +10,19 @@ import { namedLogger } from '#shared/log.ts'
|
|
|
10
10
|
import { compose } from '#shared/Middleware.ts'
|
|
11
11
|
import { MOUNT, unmounted } from '#shared/mount.ts'
|
|
12
12
|
import { RPC_SERVER } from '#shared/RPC_SERVER.ts'
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
answerRequest,
|
|
16
|
-
type LoadedSources,
|
|
17
|
-
} from './answerRequest.ts'
|
|
13
|
+
import { servedTable } from './abideModules.ts'
|
|
14
|
+
import { type AppSources, answerRequest } from './answerRequest.ts'
|
|
18
15
|
import { Mux, type MuxConnection } from './answerSocket.ts'
|
|
16
|
+
import { appDirectories } from './appDirectories.ts'
|
|
17
|
+
import { holdsAbide } from './appTree.ts'
|
|
19
18
|
import { buildDirectory } from './buildDirectory.ts'
|
|
20
19
|
import { APP_PACKAGE, type AppPackage, config, packageUnder } from './config.ts'
|
|
21
20
|
import { McpSurface } from './generatedSurfaces.ts'
|
|
22
|
-
import { HOOKS, reportUnexpected } from './hooks.ts'
|
|
21
|
+
import { HOOKS, inOrder, reportUnexpected, rootRungs } from './hooks.ts'
|
|
23
22
|
import { installServer } from './installServer.ts'
|
|
24
23
|
import { admitsMux, upgraded } from './muxUpgrade.ts'
|
|
25
24
|
import { plainAnswer } from './plainAnswer.ts'
|
|
25
|
+
import { realOrAsGiven } from './realOrAsGiven.ts'
|
|
26
26
|
import {
|
|
27
27
|
type AnsweringApp,
|
|
28
28
|
applyWritten,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
import { testBuild } from './testBuild.ts'
|
|
36
36
|
import { traceResponse } from './trace.ts'
|
|
37
37
|
|
|
38
|
-
// 28.
|
|
38
|
+
// 28.8 — one line per request.
|
|
39
39
|
const REQUEST_LOG = namedLogger('abide:request')
|
|
40
40
|
|
|
41
41
|
/** The app object: what a host, a test or a script holds the app as. */
|
|
@@ -54,29 +54,16 @@ export interface App {
|
|
|
54
54
|
[Symbol.asyncDispose](): Promise<void>
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// 37.2 — the two shapes `default` may take.
|
|
58
|
-
type OwnRoute =
|
|
59
|
-
| ((
|
|
60
|
-
request: Request,
|
|
61
|
-
server: Bun.Server<unknown> | undefined,
|
|
62
|
-
) => Response | undefined | Promise<Response | undefined>)
|
|
63
|
-
| {
|
|
64
|
-
fetch: (
|
|
65
|
-
request: Request,
|
|
66
|
-
server: Bun.Server<unknown> | undefined,
|
|
67
|
-
) => unknown
|
|
68
|
-
}
|
|
69
|
-
|
|
70
57
|
/**
|
|
71
58
|
* The app this process was started in, booted off what `abide build` left beside it.
|
|
72
59
|
*
|
|
73
|
-
* 42.1 — found where the CLI finds it (38.
|
|
60
|
+
* 42.1 — found where the CLI finds it (38.25), and booted off the build (38.27).
|
|
74
61
|
*/
|
|
75
62
|
export async function createApp(): Promise<App> {
|
|
76
63
|
const root = appRoot(undefined)
|
|
77
64
|
if (root === undefined)
|
|
78
65
|
throw new Error(
|
|
79
|
-
`abide: createApp found no app. Looked for
|
|
66
|
+
`abide: createApp found no app. Looked for a .abide under ${resolve('src')}, or under ${process.cwd()} where it has no src.`,
|
|
80
67
|
)
|
|
81
68
|
// 42.16 — under `bun test` the app is built for its sources as they stand rather than read off
|
|
82
69
|
// whatever `abide build` last left, which a test run would otherwise need first and could find
|
|
@@ -85,21 +72,34 @@ export async function createApp(): Promise<App> {
|
|
|
85
72
|
process.env.NODE_ENV === 'test'
|
|
86
73
|
? await testBuild(root)
|
|
87
74
|
: buildDirectory(root)
|
|
88
|
-
const { loadBuild } = await import('./serveBuild.ts')
|
|
75
|
+
const { loadBuild, serveBuild } = await import('./serveBuild.ts')
|
|
76
|
+
if (!(await serveBuild(root, out)))
|
|
77
|
+
throw new Error(
|
|
78
|
+
`abide: createApp found nothing under ${root} to build.`,
|
|
79
|
+
)
|
|
89
80
|
return bootApp(originUnder(root), () => loadBuild({ root, out }))
|
|
90
81
|
}
|
|
91
82
|
|
|
92
83
|
/**
|
|
93
|
-
* The
|
|
84
|
+
* The app's root — `--root`, else `src` where the working directory holds one, else the working
|
|
85
|
+
* directory — or `undefined` where it is no app's.
|
|
94
86
|
*
|
|
95
|
-
* 38.
|
|
87
|
+
* 38.25 and 38.26 — `undefined` is a refusal and not a guess. An app's root is in a package — it or
|
|
88
|
+
* the directory above it holds the `package.json` (`appDirectories`) — and holds a `.abide`
|
|
89
|
+
* file; the package is asked first, so a command run from `/` answers at once rather than
|
|
90
|
+
* walking the disk.
|
|
91
|
+
*
|
|
92
|
+
* ITS REAL PATH, as the bundler and the resolver name every file under it: an app under `/tmp` is
|
|
93
|
+
* `/private/tmp` to both, and one spelling here is one fewer at every reader downstream.
|
|
96
94
|
*/
|
|
97
95
|
export function appRoot(given: string | undefined): string | undefined {
|
|
98
|
-
if (given !== undefined) return resolve(given)
|
|
99
|
-
const here = process.cwd()
|
|
100
|
-
if (existsSync(`${here}/ui`)) return here
|
|
96
|
+
if (given !== undefined) return realOrAsGiven(resolve(given))
|
|
101
97
|
const under = resolve('src')
|
|
102
|
-
|
|
98
|
+
const root = realOrAsGiven(existsSync(under) ? under : process.cwd())
|
|
99
|
+
let packaged = false
|
|
100
|
+
for (const directory of appDirectories(root))
|
|
101
|
+
packaged ||= existsSync(`${directory}/package.json`)
|
|
102
|
+
return packaged && holdsAbide(root) ? root : undefined
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -110,26 +110,26 @@ export function appRoot(given: string | undefined): string | undefined {
|
|
|
110
110
|
* under.
|
|
111
111
|
*/
|
|
112
112
|
export type AppOrigin = {
|
|
113
|
-
/**
|
|
114
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Imports every module holding a `<script server>`, where the app has one. 37.1.
|
|
115
|
+
*
|
|
116
|
+
* Imported for what each CALLS: every hook it runs is filed by the time the import settles.
|
|
117
|
+
*/
|
|
118
|
+
hooks: (() => Promise<unknown>) | undefined
|
|
115
119
|
/** 27.3's name and version. */
|
|
116
120
|
package: AppPackage
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
/**
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** The `AppOrigin` of an app on disk, found under its source root. */
|
|
123
|
+
/**
|
|
124
|
+
* The `AppOrigin` of an app on disk: its package under `root`, and its server blocks, out of the
|
|
125
|
+
* compilation this process serves (`serveCompilation`) — the build's, or `abide dev`'s.
|
|
126
|
+
*/
|
|
126
127
|
export function originUnder(root: string): AppOrigin {
|
|
127
|
-
const hooksModule = hooksModuleUnder(root)
|
|
128
128
|
return {
|
|
129
|
-
hooks:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
hooks: async () => {
|
|
130
|
+
const table = await servedTable(root)
|
|
131
|
+
await Promise.all(table.servers.map((load) => load()))
|
|
132
|
+
},
|
|
133
133
|
package: packageUnder(root),
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -143,15 +143,12 @@ export type BootedApp = App & { openMux(): Mux }
|
|
|
143
143
|
/** An `App` booted over the sources `load` supplies, inside the app's `onStart` hooks. */
|
|
144
144
|
export async function bootApp(
|
|
145
145
|
origin: AppOrigin,
|
|
146
|
-
load: () => Promise<
|
|
146
|
+
load: () => Promise<AppSources>,
|
|
147
147
|
): Promise<BootedApp> {
|
|
148
148
|
installServer()
|
|
149
|
-
// 37.1 —
|
|
150
|
-
// import settles.
|
|
151
|
-
|
|
152
|
-
origin.hooks === undefined
|
|
153
|
-
? undefined
|
|
154
|
-
: ((await origin.hooks()).default ?? undefined)
|
|
149
|
+
// 37.1 — EVERY SERVER BLOCK, imported for what it CALLS: every hook it runs is filed by the
|
|
150
|
+
// time the import settles, which is before `onStart` is composed around the boot.
|
|
151
|
+
if (origin.hooks !== undefined) await origin.hooks()
|
|
155
152
|
|
|
156
153
|
// 37.4 — THE BOOT, INSIDE `onStart`. 37.6 — a throw out of a hook or out of the boot rejects
|
|
157
154
|
// `createApp`, and nothing is served.
|
|
@@ -159,8 +156,8 @@ export async function bootApp(
|
|
|
159
156
|
// 42.2 — THE CONFIGURATION IS READ AS PART OF THE BOOT, so a configuration that does not resolve
|
|
160
157
|
// is a boot that fails rather than a first request that does.
|
|
161
158
|
APP_PACKAGE.current = origin.package
|
|
162
|
-
let sources:
|
|
163
|
-
await compose(HOOKS.starts, async () => {
|
|
159
|
+
let sources: AppSources | undefined
|
|
160
|
+
await compose(inOrder(HOOKS.starts), async () => {
|
|
164
161
|
config.invalidate()
|
|
165
162
|
await config
|
|
166
163
|
sources = await load()
|
|
@@ -169,17 +166,16 @@ export async function bootApp(
|
|
|
169
166
|
throw new Error(
|
|
170
167
|
'abide: an onStart hook returned without calling start(), so the app never booted. RULEBOOK 37.4.',
|
|
171
168
|
)
|
|
172
|
-
const booted
|
|
173
|
-
...sources,
|
|
174
|
-
own: own === undefined ? undefined : ownRoute(own),
|
|
175
|
-
}
|
|
169
|
+
const booted = sources
|
|
176
170
|
|
|
177
|
-
// 16.14, 37.3 — THE APP LANE'S ONION, composed once over the whole request path
|
|
178
|
-
//
|
|
179
|
-
|
|
171
|
+
// 16.14, 37.3 — THE APP LANE'S ONION, composed once over the whole request path: the root
|
|
172
|
+
// route's rungs, the ones below it running after routing (37.2, `answerRequest`). 21.20 — the
|
|
173
|
+
// center takes its own time back out of what `fetch` counts for the whole onion.
|
|
174
|
+
const rungs = rootRungs()
|
|
175
|
+
const answer = compose(rungs, async ({ request }) => {
|
|
180
176
|
const began = performance.now()
|
|
181
177
|
const answered = await answerRequest(booted, request)
|
|
182
|
-
if (
|
|
178
|
+
if (rungs.length > 0) rungsTook(began - performance.now())
|
|
183
179
|
return answered
|
|
184
180
|
})
|
|
185
181
|
|
|
@@ -213,14 +209,14 @@ export async function bootApp(
|
|
|
213
209
|
let answered: Response
|
|
214
210
|
try {
|
|
215
211
|
answered = await answer({ request })
|
|
216
|
-
if (
|
|
212
|
+
if (rungs.length > 0)
|
|
217
213
|
rungsTook(performance.now() - started)
|
|
218
214
|
} catch (thrown) {
|
|
219
215
|
reportUnexpected(thrown)
|
|
220
216
|
answered = plainAnswer('internal server error', 500)
|
|
221
217
|
}
|
|
222
218
|
const stamped = stamp(answered)
|
|
223
|
-
// 28.
|
|
219
|
+
// 28.7 — a closed namespace does not pay for the line it would have written.
|
|
224
220
|
if (REQUEST_LOG.enabled())
|
|
225
221
|
REQUEST_LOG.debug(
|
|
226
222
|
request.method,
|
|
@@ -289,7 +285,7 @@ export async function bootApp(
|
|
|
289
285
|
// 16.42 — a stopped app answers no `raw` call made outside every request.
|
|
290
286
|
if (RPC_SERVER.raw === answerRaw) RPC_SERVER.raw = null
|
|
291
287
|
bound = undefined
|
|
292
|
-
await compose(HOOKS.stops, async () => {})(undefined)
|
|
288
|
+
await compose(inOrder(HOOKS.stops), async () => {})(undefined)
|
|
293
289
|
}
|
|
294
290
|
|
|
295
291
|
return {
|
|
@@ -416,13 +412,3 @@ function belowMount(request: Request): Request | Response {
|
|
|
416
412
|
url.pathname = below
|
|
417
413
|
return new Request(url, request)
|
|
418
414
|
}
|
|
419
|
-
|
|
420
|
-
function ownRoute(
|
|
421
|
-
own: OwnRoute,
|
|
422
|
-
): (request: Request) => Promise<Response | undefined> {
|
|
423
|
-
const answer = typeof own === 'function' ? own : own.fetch.bind(own)
|
|
424
|
-
return async (request) => {
|
|
425
|
-
const answered = await answer(request, LISTENING.server)
|
|
426
|
-
return answered instanceof Response ? answered : undefined
|
|
427
|
-
}
|
|
428
|
-
}
|