@springbrand/space 0.2.0-alpha.14 → 0.2.0-alpha.15

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