@springbrand/space 0.2.0-alpha.12 → 0.2.0-alpha.14
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/package.json +9 -2
- package/src/index.ts +3 -3
- package/src/space/default-durable-object.ts +13 -0
- package/src/space/deploy-engine.ts +20 -53
- package/src/space/deployment-contract.ts +54 -0
- package/src/space/durable-object.ts +26 -9
- package/src/space/runtime/deploy-engine.d.ts +1 -0
- package/src/space/runtime/deploy-engine.js +907 -0
- package/src/space/runtime/deploy-engine.js.map +7 -0
- package/src/space/runtime/esbuild-7EQXV6JP.wasm +0 -0
- package/src/space/workspace-port.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@springbrand/space",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
|
-
".": "./src/index.ts"
|
|
13
|
+
".": "./src/index.ts",
|
|
14
|
+
"./deployment-contract": "./src/space/deployment-contract.ts",
|
|
15
|
+
"./deploy-engine": "./src/space/deploy-engine.ts",
|
|
16
|
+
"./lazy-space-do": "./src/space/durable-object.ts",
|
|
17
|
+
"./preview-headers": "./src/space/preview-headers.ts"
|
|
14
18
|
},
|
|
15
19
|
"dependencies": {
|
|
16
20
|
"@cloudflare/shell": "0.4.3",
|
|
@@ -20,11 +24,14 @@
|
|
|
20
24
|
"devDependencies": {
|
|
21
25
|
"@cloudflare/vitest-pool-workers": "^0.20.1",
|
|
22
26
|
"@cloudflare/workers-types": "^4.20251008.0",
|
|
27
|
+
"esbuild": "0.28.1",
|
|
23
28
|
"typescript": "^7.0.2",
|
|
24
29
|
"vitest": "^4.1.10"
|
|
25
30
|
},
|
|
26
31
|
"scripts": {
|
|
32
|
+
"build": "node build.mjs",
|
|
27
33
|
"check": "tsc --noEmit",
|
|
34
|
+
"pretest": "pnpm build",
|
|
28
35
|
"test": "vitest run"
|
|
29
36
|
}
|
|
30
37
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ── Durable Object classes ────────────────────────────────────────
|
|
2
|
-
export { SpaceDO } from "./space/durable-object";
|
|
2
|
+
export { SpaceDO } from "./space/default-durable-object";
|
|
3
3
|
|
|
4
4
|
// ── RPC surface ───────────────────────────────────────────────────
|
|
5
5
|
export type {
|
|
@@ -22,14 +22,14 @@ export { SPACE_RESERVED_PREFIXES } from "./space/durable-object";
|
|
|
22
22
|
export {
|
|
23
23
|
deploymentRuntimeConfigSource,
|
|
24
24
|
RUNTIME_CONFIG_ASSET_PATH,
|
|
25
|
-
} from "./space/
|
|
25
|
+
} from "./space/deployment-contract";
|
|
26
26
|
export type {
|
|
27
27
|
BranchDeploymentBundle,
|
|
28
28
|
DeploymentAsset,
|
|
29
29
|
DeploymentBundle,
|
|
30
30
|
DeploymentRuntimeConfig,
|
|
31
31
|
SpaceDeploymentResult,
|
|
32
|
-
} from "./space/
|
|
32
|
+
} from "./space/deployment-contract";
|
|
33
33
|
|
|
34
34
|
// ── Preview hardening ─────────────────────────────────────────────
|
|
35
35
|
export { stripPreviewSecurityHeaders, STRIPPED_PREVIEW_HEADERS } from "./space/preview-headers";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSpaceDO,
|
|
3
|
+
type DeployEngine,
|
|
4
|
+
} from "./durable-object"
|
|
5
|
+
|
|
6
|
+
let deployEnginePromise: Promise<DeployEngine> | undefined
|
|
7
|
+
|
|
8
|
+
const DefaultSpaceDO = createSpaceDO(
|
|
9
|
+
() => deployEnginePromise ??= import("@springbrand/space/deploy-engine"),
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
export const SpaceDO = DefaultSpaceDO
|
|
13
|
+
export type SpaceDO = InstanceType<typeof DefaultSpaceDO>
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { Git } from "@cloudflare/shell/git"
|
|
2
|
-
import type { FileSystem } from "@cloudflare/shell"
|
|
3
1
|
import {
|
|
4
2
|
createWorker,
|
|
5
3
|
inferContentType,
|
|
@@ -7,6 +5,15 @@ import {
|
|
|
7
5
|
type AssetConfig,
|
|
8
6
|
type Modules,
|
|
9
7
|
} from "@cloudflare/worker-bundler"
|
|
8
|
+
import {
|
|
9
|
+
deploymentRuntimeConfigSource,
|
|
10
|
+
RUNTIME_CONFIG_ASSET_PATH,
|
|
11
|
+
type BranchDeploymentBundle,
|
|
12
|
+
type DeployContext,
|
|
13
|
+
type DeploymentAsset,
|
|
14
|
+
type DeploymentRuntimeConfig,
|
|
15
|
+
type SpaceDeploymentResult,
|
|
16
|
+
} from "./deployment-contract"
|
|
10
17
|
import { globInfos } from "./fileinfo"
|
|
11
18
|
import {
|
|
12
19
|
parseWranglerConfig,
|
|
@@ -14,6 +21,17 @@ import {
|
|
|
14
21
|
WranglerConfigError,
|
|
15
22
|
} from "./wrangler-config"
|
|
16
23
|
|
|
24
|
+
export {
|
|
25
|
+
deploymentRuntimeConfigSource,
|
|
26
|
+
RUNTIME_CONFIG_ASSET_PATH,
|
|
27
|
+
type BranchDeploymentBundle,
|
|
28
|
+
type DeployContext,
|
|
29
|
+
type DeploymentAsset,
|
|
30
|
+
type DeploymentBundle,
|
|
31
|
+
type DeploymentRuntimeConfig,
|
|
32
|
+
type SpaceDeploymentResult,
|
|
33
|
+
} from "./deployment-contract"
|
|
34
|
+
|
|
17
35
|
// ─── Deploy Engine ──────────────────────────────────────────────────────────
|
|
18
36
|
|
|
19
37
|
/** Shared JSON response helper for the internal deploy command handlers. */
|
|
@@ -24,53 +42,6 @@ function jsonResponse(data: unknown, status: number = 200): Response {
|
|
|
24
42
|
})
|
|
25
43
|
}
|
|
26
44
|
|
|
27
|
-
export interface DeployContext {
|
|
28
|
-
sql: SqlStorage
|
|
29
|
-
git: Git
|
|
30
|
-
fs: FileSystem
|
|
31
|
-
assetBucket?: R2Bucket
|
|
32
|
-
assetPrefix?: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface DeploymentBundle {
|
|
36
|
-
branch: string
|
|
37
|
-
commitHash: string
|
|
38
|
-
workerModules: {
|
|
39
|
-
mainModule: string
|
|
40
|
-
modules: Record<string, string | Record<string, unknown>>
|
|
41
|
-
compatibilityDate: string
|
|
42
|
-
}
|
|
43
|
-
staticAssets: DeploymentAsset[]
|
|
44
|
-
assetConfig: AssetConfig | undefined
|
|
45
|
-
runtimeConfig: DeploymentRuntimeConfig | undefined
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export type BranchDeploymentBundle = DeploymentBundle
|
|
49
|
-
|
|
50
|
-
export interface DeploymentRuntimeConfig {
|
|
51
|
-
apiBaseUrl: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface SpaceDeploymentResult {
|
|
55
|
-
branch: string
|
|
56
|
-
commit_hash: string
|
|
57
|
-
main_module: string
|
|
58
|
-
has_assets: boolean
|
|
59
|
-
compatibility_date: string
|
|
60
|
-
deployed_at: string
|
|
61
|
-
asset_root: string | null
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export const RUNTIME_CONFIG_ASSET_PATH = "/.springbrand/runtime-config.js"
|
|
65
|
-
|
|
66
|
-
export interface DeploymentAsset {
|
|
67
|
-
path: string
|
|
68
|
-
sourcePath: string | null
|
|
69
|
-
contentType: string | undefined
|
|
70
|
-
etag: string
|
|
71
|
-
size: number
|
|
72
|
-
}
|
|
73
|
-
|
|
74
45
|
type AssetWriter = (
|
|
75
46
|
asset: Omit<DeploymentAsset, "etag">,
|
|
76
47
|
bytes: Uint8Array,
|
|
@@ -436,10 +407,6 @@ function normalizeRuntimeConfig(
|
|
|
436
407
|
return { apiBaseUrl: url.toString() }
|
|
437
408
|
}
|
|
438
409
|
|
|
439
|
-
export function deploymentRuntimeConfigSource(config: DeploymentRuntimeConfig): string {
|
|
440
|
-
return `globalThis.__APP_CONFIG__=Object.freeze(${JSON.stringify(config)});`
|
|
441
|
-
}
|
|
442
|
-
|
|
443
410
|
async function buildWebsite(
|
|
444
411
|
sourceFiles: Record<string, string>,
|
|
445
412
|
config: ParsedWranglerConfig,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { FileSystem } from "@cloudflare/shell"
|
|
2
|
+
import type { Git } from "@cloudflare/shell/git"
|
|
3
|
+
import type { AssetConfig } from "@cloudflare/worker-bundler"
|
|
4
|
+
|
|
5
|
+
export interface DeployContext {
|
|
6
|
+
sql: SqlStorage
|
|
7
|
+
git: Git
|
|
8
|
+
fs: FileSystem
|
|
9
|
+
assetBucket?: R2Bucket
|
|
10
|
+
assetPrefix?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DeploymentBundle {
|
|
14
|
+
branch: string
|
|
15
|
+
commitHash: string
|
|
16
|
+
workerModules: {
|
|
17
|
+
mainModule: string
|
|
18
|
+
modules: Record<string, string | Record<string, unknown>>
|
|
19
|
+
compatibilityDate: string
|
|
20
|
+
}
|
|
21
|
+
staticAssets: DeploymentAsset[]
|
|
22
|
+
assetConfig: AssetConfig | undefined
|
|
23
|
+
runtimeConfig: DeploymentRuntimeConfig | undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type BranchDeploymentBundle = DeploymentBundle
|
|
27
|
+
|
|
28
|
+
export interface DeploymentRuntimeConfig {
|
|
29
|
+
apiBaseUrl: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SpaceDeploymentResult {
|
|
33
|
+
branch: string
|
|
34
|
+
commit_hash: string
|
|
35
|
+
main_module: string
|
|
36
|
+
has_assets: boolean
|
|
37
|
+
compatibility_date: string
|
|
38
|
+
deployed_at: string
|
|
39
|
+
asset_root: string | null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface DeploymentAsset {
|
|
43
|
+
path: string
|
|
44
|
+
sourcePath: string | null
|
|
45
|
+
contentType: string | undefined
|
|
46
|
+
etag: string
|
|
47
|
+
size: number
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const RUNTIME_CONFIG_ASSET_PATH = "/.springbrand/runtime-config.js"
|
|
51
|
+
|
|
52
|
+
export function deploymentRuntimeConfigSource(config: DeploymentRuntimeConfig): string {
|
|
53
|
+
return `globalThis.__APP_CONFIG__=Object.freeze(${JSON.stringify(config)});`
|
|
54
|
+
}
|
|
@@ -2,14 +2,12 @@ import { DurableObject } from "cloudflare:workers"
|
|
|
2
2
|
import { type FileSystem, type FileInfo } from "@cloudflare/shell"
|
|
3
3
|
import { type Git, type GitLogEntry, type GitStatusEntry } from "@cloudflare/shell/git"
|
|
4
4
|
import type { Env } from "../env"
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type SpaceDeploymentResult,
|
|
12
|
-
} from "./deploy-engine"
|
|
5
|
+
import type {
|
|
6
|
+
BranchDeploymentBundle,
|
|
7
|
+
DeploymentRuntimeConfig,
|
|
8
|
+
DeployContext,
|
|
9
|
+
SpaceDeploymentResult,
|
|
10
|
+
} from "./deployment-contract"
|
|
13
11
|
import { globInfos, readDirInfos, toFileInfo } from "./fileinfo"
|
|
14
12
|
import {
|
|
15
13
|
buildInspectorWrapperSource,
|
|
@@ -61,6 +59,9 @@ export type {
|
|
|
61
59
|
/** The complete capability a host holds over one Space. */
|
|
62
60
|
export type SpaceStub = SpaceWorkspacePort & SpaceControlPort & SpaceAppPort
|
|
63
61
|
|
|
62
|
+
export type DeployEngine = typeof import("@springbrand/space/deploy-engine")
|
|
63
|
+
export type DeployEngineLoader = () => Promise<DeployEngine>
|
|
64
|
+
|
|
64
65
|
// ─── Inspector result types ────────────────────────────────────────────────
|
|
65
66
|
// These mirror the shapes returned by the wrapper-subclass injected into
|
|
66
67
|
// the dynamic worker (see `inspector-wrapper.ts`). Re-exported at the
|
|
@@ -110,7 +111,7 @@ const isReservedPath = isReservedSpacePath
|
|
|
110
111
|
// Commits/deploys are mirrored to a per-app Cloudflare Artifacts repo
|
|
111
112
|
// (see artifacts-sync.ts), which is the durable source of truth for history.
|
|
112
113
|
|
|
113
|
-
export class
|
|
114
|
+
export abstract class SpaceDOBase extends DurableObject<Env>
|
|
114
115
|
implements SpaceWorkspacePort, SpaceControlPort, SpaceAppPort {
|
|
115
116
|
private backend!: SpaceFsBackend
|
|
116
117
|
private initializationPromise: Promise<void> | null = null
|
|
@@ -133,6 +134,8 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
133
134
|
super(ctx, env)
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
protected abstract loadDeployEngine(): Promise<DeployEngine>
|
|
138
|
+
|
|
136
139
|
private async flushCheckpoint(): Promise<void> {
|
|
137
140
|
await this.backend.flushCheckpoint()
|
|
138
141
|
}
|
|
@@ -1110,6 +1113,7 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1110
1113
|
): Promise<SpaceDeploymentResult> {
|
|
1111
1114
|
await this.ensureInit()
|
|
1112
1115
|
return this.lane(async () => {
|
|
1116
|
+
const { handleDeployCommand } = await this.loadDeployEngine()
|
|
1113
1117
|
// The deploy engine reads the full branch tree, so ensure the Artifacts
|
|
1114
1118
|
// base is materialized into the overlay first.
|
|
1115
1119
|
await this.materializeAll()
|
|
@@ -1149,6 +1153,7 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1149
1153
|
): Promise<BranchDeploymentBundle> {
|
|
1150
1154
|
await this.ensureInit()
|
|
1151
1155
|
await this.materializeAll()
|
|
1156
|
+
const { buildBranchDeployment } = await this.loadDeployEngine()
|
|
1152
1157
|
return buildBranchDeployment(
|
|
1153
1158
|
{
|
|
1154
1159
|
sql: this.ctx.storage.sql,
|
|
@@ -1165,6 +1170,7 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1165
1170
|
|
|
1166
1171
|
async undeploy(branch: string): Promise<unknown> {
|
|
1167
1172
|
await this.ensureInit()
|
|
1173
|
+
const { handleDeployCommand } = await this.loadDeployEngine()
|
|
1168
1174
|
const fakeRequest = new Request("http://internal/?cmd=undeploy", {
|
|
1169
1175
|
method: "POST",
|
|
1170
1176
|
headers: { "Content-Type": "application/json" },
|
|
@@ -1183,6 +1189,7 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1183
1189
|
|
|
1184
1190
|
async listDeployments(): Promise<unknown> {
|
|
1185
1191
|
await this.ensureInit()
|
|
1192
|
+
const { handleDeployCommand } = await this.loadDeployEngine()
|
|
1186
1193
|
const fakeRequest = new Request("http://internal/?cmd=list_deployments")
|
|
1187
1194
|
const ctx: DeployContext = {
|
|
1188
1195
|
sql: this.ctx.storage.sql,
|
|
@@ -1195,6 +1202,7 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1195
1202
|
|
|
1196
1203
|
async getDeployment(branch: string): Promise<unknown> {
|
|
1197
1204
|
await this.ensureInit()
|
|
1205
|
+
const { handleDeployCommand } = await this.loadDeployEngine()
|
|
1198
1206
|
const fakeRequest = new Request(`http://internal/?cmd=get_deployment&branch=${encodeURIComponent(branch)}`)
|
|
1199
1207
|
const ctx: DeployContext = {
|
|
1200
1208
|
sql: this.ctx.storage.sql,
|
|
@@ -1392,6 +1400,7 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1392
1400
|
|
|
1393
1401
|
const cmd = new URL(request.url).searchParams.get("cmd")
|
|
1394
1402
|
if (cmd && ["deploy", "get_deployment", "list_deployments", "undeploy"].includes(cmd)) {
|
|
1403
|
+
const { handleDeployCommand } = await this.loadDeployEngine()
|
|
1395
1404
|
const deployCtx: DeployContext = {
|
|
1396
1405
|
sql: this.ctx.storage.sql,
|
|
1397
1406
|
git: this.git,
|
|
@@ -1406,6 +1415,14 @@ export class SpaceDO extends DurableObject<Env>
|
|
|
1406
1415
|
}
|
|
1407
1416
|
}
|
|
1408
1417
|
|
|
1418
|
+
export function createSpaceDO(loadDeployEngine: DeployEngineLoader): typeof SpaceDOBase {
|
|
1419
|
+
return class SpaceDO extends SpaceDOBase {
|
|
1420
|
+
protected loadDeployEngine(): Promise<DeployEngine> {
|
|
1421
|
+
return loadDeployEngine()
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1409
1426
|
// ─── Facet naming ───────────────────────────────────────────────────────────
|
|
1410
1427
|
|
|
1411
1428
|
function facetNameForApp(branch: string): string {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@springbrand/space/deploy-engine"
|