@pikku/deploy-standalone 0.12.12 → 0.12.17

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/dist/adapter.d.ts +45 -0
  3. package/dist/adapter.js +448 -6
  4. package/dist/runtime/cli.d.ts +75 -0
  5. package/dist/runtime/cli.js +193 -0
  6. package/dist/runtime/index.d.ts +11 -0
  7. package/dist/runtime/index.js +9 -0
  8. package/dist/runtime/parent-watch.d.ts +45 -0
  9. package/dist/runtime/parent-watch.js +87 -0
  10. package/dist/tauri/generate.d.ts +45 -0
  11. package/dist/tauri/generate.js +230 -0
  12. package/dist/tauri/icon.d.ts +1 -0
  13. package/dist/tauri/icon.js +54 -0
  14. package/dist/tauri/main-rs.d.ts +31 -0
  15. package/dist/tauri/main-rs.js +213 -0
  16. package/dist/tauri/next-steps.d.ts +15 -0
  17. package/dist/tauri/next-steps.js +16 -0
  18. package/dist/tauri/target-triple.d.ts +29 -0
  19. package/dist/tauri/target-triple.js +42 -0
  20. package/knowledge/decisions/a-pikku-server-serves-a-static-frontend.md +36 -0
  21. package/knowledge/decisions/a-remote-desktop-shell-bundles-nothing.md +38 -0
  22. package/knowledge/decisions/deploy-consumes-a-built-frontend.md +33 -0
  23. package/knowledge/decisions/desktop-builds-are-unsigned-and-never-update-themselves.md +34 -0
  24. package/knowledge/decisions/index.md +19 -0
  25. package/knowledge/decisions/standalone-assets-are-embedded-in-the-bun-binary.md +39 -0
  26. package/knowledge/decisions/the-desktop-shell-runs-the-server-as-a-sidecar.md +51 -0
  27. package/knowledge/decisions/the-sidecar-reports-its-port-the-shell-never-picks-one.md +44 -0
  28. package/knowledge/index.md +22 -0
  29. package/package.json +7 -4
  30. package/src/adapter.test.ts +725 -0
  31. package/src/adapter.ts +508 -6
  32. package/src/desktop-deploy.test.ts +167 -0
  33. package/src/runtime/cli.test.ts +222 -0
  34. package/src/runtime/cli.ts +311 -0
  35. package/src/runtime/index.ts +31 -0
  36. package/src/runtime/parent-watch.process.test.ts +112 -0
  37. package/src/runtime/parent-watch.test.ts +148 -0
  38. package/src/runtime/parent-watch.ts +115 -0
  39. package/src/sidecar-entry.test.ts +89 -0
  40. package/src/tauri/generate.test.ts +401 -0
  41. package/src/tauri/generate.ts +327 -0
  42. package/src/tauri/icon.test.ts +63 -0
  43. package/src/tauri/icon.ts +62 -0
  44. package/src/tauri/main-rs.rustfmt.test.ts +86 -0
  45. package/src/tauri/main-rs.ts +241 -0
  46. package/src/tauri/next-steps.test.ts +38 -0
  47. package/src/tauri/next-steps.ts +30 -0
  48. package/src/tauri/target-triple.test.ts +84 -0
  49. package/src/tauri/target-triple.ts +65 -0
  50. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,182 @@
1
1
  # @pikku/deploy-standalone
2
2
 
3
+ ## 0.12.17
4
+
5
+ ### Patch Changes
6
+
7
+ - b2e038b: Rename `@pikku/sql-migrator` to `@pikku/migrator-sql`, so a future migrator for
8
+ another store sorts beside it rather than under a second prefix. The package has
9
+ never been published under either name, so nothing depends on the old one.
10
+ - Updated dependencies [b2e038b]
11
+ - @pikku/migrator-sql@0.12.3
12
+
13
+ ## 0.12.16
14
+
15
+ ### Patch Changes
16
+
17
+ - f970f8f: Rename `@pikku/db-migrator` to `@pikku/migrator-sql`.
18
+
19
+ It applies `.sql` files and keeps their bookkeeping; it is not a database
20
+ service, and `db-` read as though it were one. Nothing was ever published under
21
+ the old name, so there is no alias to keep.
22
+
23
+ - Updated dependencies [f970f8f]
24
+ - @pikku/migrator-sql@0.12.2
25
+
26
+ ## 0.12.15
27
+
28
+ ### Patch Changes
29
+
30
+ - a057bec: Give a standalone bundle a command line.
31
+
32
+ An operator holding a standalone artifact on a machine had one thing they could
33
+ do with it: start it. Applying the migrations it needs meant a checkout of the
34
+ project and a second copy of the CLI on a production box, and answering "which
35
+ build is this" meant asking whoever ran the deploy.
36
+
37
+ The bundle now takes a command. `serve` remains the default, so an existing
38
+ `node bundle.js` is unchanged. `version` prints the version the project declared
39
+ at build time. `db migrate` and `db status` apply and report the migrations that
40
+ now ship beside the bundle under `db/<engine>/` — the same path Fabric's build
41
+ container stages them to, so the two producers of an artifact cannot disagree
42
+ about where the SQL lives. `backup <path>` writes a consistent copy of a SQLite
43
+ database with `VACUUM INTO`; on postgres it refuses and names `pg_dump`, which
44
+ is the tool for it.
45
+
46
+ Both engines are supported: a postgres build migrates over the connection it
47
+ already opens. `PostgresMigrationClient` grew an optional `begin`, because a
48
+ pooled client is free to answer `BEGIN`, the migration and `COMMIT` on three
49
+ different connections — which leaves a failed migration half applied with
50
+ nothing to roll back.
51
+
52
+ There is deliberately no way to invoke an RPC. A running server already answers
53
+ them with auth, sessions and middleware applied; an in-process invoke would
54
+ answer them with none of that.
55
+
56
+ - Updated dependencies [a057bec]
57
+ - Updated dependencies [a057bec]
58
+ - @pikku/migrator-sql@0.12.1
59
+ - @pikku/deploy@0.12.5
60
+
61
+ ## 0.12.14
62
+
63
+ ### Patch Changes
64
+
65
+ - 3d75643: Run the app's server lifecycle in generated entries, and make an out-of-band
66
+ account signable-in.
67
+
68
+ `pikkuServerLifecycle` was only ever called by `pikku dev` and `pikku serve`, so
69
+ an app that seeds its first admin account, probes a dependency, or warms a cache
70
+ in `beforeStart` did all of that in development and silently skipped it
71
+ everywhere it was actually deployed. The standalone entry and the shared node
72
+ server entry — the one behind every `target: 'server'` unit — now import the
73
+ app's lifecycle and call it: `beforeStart` after `init` and before the port
74
+ opens, so work that must finish before the first request has, `afterStart` once
75
+ the server is listening, and the stop hooks handed to the signal handler that
76
+ already owns shutdown rather than a second listener racing it. Each shutdown
77
+ step is isolated from the ones after it, so a hook that throws is logged without
78
+ taking the service teardown and the socket close down with it.
79
+
80
+ Separately, `createAuthUser` and `setAuthUserPassword` wrote credential accounts
81
+ with no `issuer`. From better-auth 1.7 a credential account is matched by its
82
+ issuer as well as its provider, so those accounts were invisible to sign-in,
83
+ `updatePassword` and `findCredentialAccount` — a user who plainly existed in the
84
+ table was reported as "user not found". The field is written only when the
85
+ resolved schema has it, so older better-auth keeps working, and
86
+ `setAuthUserPassword` repairs an account that predates the fix.
87
+
88
+ - 3d75643: Give a standalone artifact the database connection every other provider's runtime hands it.
89
+
90
+ `createSingletonServices` receives `kysely` from whatever is hosting the app —
91
+ `pikku dev` builds one, a Cloudflare deploy binds one — so app code is written
92
+ expecting it, and the generated templates throw outright when it is absent. The
93
+ standalone provider is its own host and supplied nothing, so a bundle built from
94
+ a project with a database started, called the services factory, and died on the
95
+ first line of it. The artifact was only ever startable by projects that had no
96
+ database at all, which is not the case the provider exists to serve.
97
+
98
+ The generated entry now opens the database itself and passes `kysely` in.
99
+ `EntryGenerationContext` carries a `db` descriptor, and the engine is read from
100
+ the migrations directory the project actually wrote — `db/sqlite` or
101
+ `db/postgres`, the same two conventions the migrator emits to. Having both is
102
+ refused rather than resolved: choosing on directory order would choose which
103
+ database the deployed app talks to, and an app running happily against the
104
+ wrong but entirely valid schema is invisible until someone reads the data.
105
+
106
+ For SQLite the adapter emits the dialect its runtime can actually use —
107
+ `@pikku/kysely-node-sqlite` for the node bundle, `@pikku/kysely-bun-sqlite` for a
108
+ compiled bun binary, which has no `node:sqlite` to reach for. For Postgres it
109
+ emits `PikkuKysely` from `@pikku/kysely-postgres`, connected from `DATABASE_URL`,
110
+ the same variable every other pikku host reads, so an artifact dropped onto a
111
+ machine already running a pikku app needs no new one. An unset `DATABASE_URL`
112
+ fails by name rather than as a driver error about an undefined connection
113
+ string.
114
+
115
+ The connection pool is closed on shutdown, in `afterStop` — after the app's own
116
+ stop hook and the draining server have both finished with it, since a pool
117
+ closed any earlier takes the queries they are still entitled to make down with
118
+ it. SQLite needs no counterpart: the process exiting releases the file.
119
+
120
+ The project's generated coercion map is applied to either engine, so a deployed
121
+ app and `pikku dev` agree about which columns are dates and which are booleans.
122
+ It is attached when the project generated one and skipped when it did not — the
123
+ map is built from `db/annotations.ts` rather than from the dialect, so an app
124
+ that annotates no columns is one with nothing to coerce rather than one that
125
+ should be handed no database at all.
126
+
127
+ A SQLite file is located by `PIKKU_DATA_DIR` rather than derived from the bundle's
128
+ own path: a deploy that swaps the release directory would otherwise take the
129
+ database with it. `PIKKU_DATABASE_FILE` overrides it outright, for when the path
130
+ has to match one something else already chose — notably `pikku db migrate`,
131
+ which has to open the same file or the app runs against an unmigrated schema.
132
+ Neither being set fails with the variable's name rather than as a SQLite error
133
+ about a path of `undefined`.
134
+
135
+ - Updated dependencies [3d75643]
136
+ - Updated dependencies [3d75643]
137
+ - @pikku/deploy@0.12.4
138
+
139
+ ## 0.12.13
140
+
141
+ ### Patch Changes
142
+
143
+ - 80eb5c0: Generate a desktop shell from `pikku deploy apply --desktop`
144
+
145
+ `pikku deploy apply --provider standalone --runtime bun --desktop` now emits a
146
+ `src-tauri/` crate that ships the compiled binary as a sidecar and opens a
147
+ window on the server's own HTTP origin, so cookies, CORS and OAuth behave
148
+ exactly as they do in a browser. Regeneration is idempotent and leaves an
149
+ edited file alone rather than overwriting it.
150
+
151
+ `--desktop-url https://app.example.com` builds the other shape: a shell that
152
+ points at an already-deployed server. Nothing is bundled — no sidecar, no
153
+ binary, and so no bun runtime to compile one — and the window is declared in
154
+ `tauri.conf.json` rather than opened from Rust, because the origin is known up
155
+ front. The url can also live in `pikku.config.json` as `deploy.desktop.url`,
156
+ alongside `deploy.desktop.identifier`.
157
+
158
+ Supporting changes: `SERVER_READY_MARKER` moved to `@pikku/deploy` (the CLI
159
+ re-exports it from its old path), both HTTP runtimes expose the port they
160
+ actually bound so `--port 0` reports a real port, and the generated server
161
+ entry exits when its parent process goes away.
162
+
163
+ - 80eb5c0: feat: serve a built frontend from the pikku server's own origin
164
+
165
+ A new `frontend` key in `pikku.config.json` names a directory of built
166
+ frontend output. `pikku serve` mounts it, and `pikku deploy` ships it inside
167
+ the distributable — into a directory beside the bundle for the node runtime,
168
+ and embedded in the binary for a `bun build --compile` standalone. `pikku dev`
169
+ deliberately ignores it and says so, because the frontend's own dev server owns
170
+ that job.
171
+
172
+ Pikku reads the frontend's output and never builds it, so an unbuilt directory
173
+ fails with a message that says which build to run rather than booting a server
174
+ that answers every page with a 404.
175
+
176
+ - Updated dependencies [80eb5c0]
177
+ - Updated dependencies [80eb5c0]
178
+ - @pikku/deploy@0.12.2
179
+
3
180
  ## 0.12.12
4
181
 
5
182
  ### Patch Changes
package/dist/adapter.d.ts CHANGED
@@ -18,14 +18,46 @@
18
18
  */
19
19
  import type { EntryGenerationContext, ProviderAdapter } from '@pikku/deploy';
20
20
  export type StandaloneRuntime = 'node' | 'bun';
21
+ /**
22
+ * Directory the built frontend is copied to, both inside the unit and beside
23
+ * the shipped bundle. The node entry resolves it relative to itself at runtime,
24
+ * so the two have to agree.
25
+ */
26
+ export declare const STANDALONE_FRONTEND_DIR = "frontend";
27
+ /**
28
+ * Module the bun entry imports its embedded assets from. It stays out of the
29
+ * esbuild bundle — esbuild rejects the `with { type: 'file' }` attribute the
30
+ * manifest is built on — and is resolved by `bun build --compile` instead.
31
+ */
32
+ export declare const STANDALONE_FRONTEND_MANIFEST = "./frontend-assets.gen.js";
21
33
  export interface StandaloneProviderAdapterOptions {
22
34
  runtime?: StandaloneRuntime;
35
+ /**
36
+ * Generate a desktop shell (Tauri) around the compiled binary. Requires the
37
+ * `bun` runtime — the shell ships the binary as a sidecar, and only that
38
+ * runtime produces one. A shell pointed at {@link desktopUrl} ships no binary
39
+ * and so has no such requirement.
40
+ */
41
+ desktop?: boolean;
42
+ /** Project root. The shell crate is written to `<projectDir>/src-tauri`. */
43
+ projectDir?: string;
44
+ /** Bundle identifier for the shell. Derived from the app name when absent. */
45
+ desktopIdentifier?: string;
46
+ /**
47
+ * An already-deployed server for the shell to open, instead of bundling one.
48
+ * The window is a webview onto that origin and nothing else is shipped.
49
+ */
50
+ desktopUrl?: string;
23
51
  }
24
52
  export declare class StandaloneProviderAdapter implements ProviderAdapter {
25
53
  readonly name = "standalone";
26
54
  readonly deployDirName = "standalone";
27
55
  readonly singleUnit = true;
28
56
  readonly runtime: StandaloneRuntime;
57
+ readonly desktop: boolean;
58
+ readonly projectDir?: string;
59
+ readonly desktopIdentifier?: string;
60
+ readonly desktopUrl?: string;
29
61
  constructor(options?: StandaloneProviderAdapterOptions);
30
62
  generateEntrySource(ctx: EntryGenerationContext): string;
31
63
  private generateNodeEntrySource;
@@ -34,6 +66,17 @@ export declare class StandaloneProviderAdapter implements ProviderAdapter {
34
66
  generateInfraManifest(): string | null;
35
67
  generateProviderConfigs(): Map<string, string>;
36
68
  getExternals(): string[];
69
+ /**
70
+ * The SQLite driver this runtime cannot load.
71
+ *
72
+ * `loadSqliteRuntime` picks its driver by looking for `globalThis.Bun`, so a
73
+ * node process never runs the bun branch — but esbuild still follows the
74
+ * import, and `bun:sqlite` sits at the top of that module as a static import
75
+ * it cannot resolve. Left in, the bundle fails to build; marked external, it
76
+ * becomes a top-level import node fails to load. Stubbing removes the branch
77
+ * that was already dead.
78
+ */
79
+ getStubModules(): string[];
37
80
  getPlatform(): 'node';
38
81
  deploy(options: {
39
82
  buildDir: string;
@@ -50,10 +93,12 @@ export declare class StandaloneProviderAdapter implements ProviderAdapter {
50
93
  }[];
51
94
  workersDeployed?: undefined;
52
95
  resourcesCreated?: undefined;
96
+ targetTriple?: undefined;
53
97
  } | {
54
98
  success: boolean;
55
99
  workersDeployed: string[];
56
100
  resourcesCreated: never[];
57
101
  errors: never[];
102
+ targetTriple: string | undefined;
58
103
  }>;
59
104
  }