pixelkiln 0.26.0 → 0.28.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/dist/index.d.cts CHANGED
@@ -7543,8 +7543,11 @@ type GalleryState = PlanState | "undeclared";
7543
7543
  interface GalleryMedia {
7544
7544
  /** Absolute path of the file the server may read for this id. */
7545
7545
  path: string;
7546
- contentType: MediaType;
7546
+ /** Images, or the editor's own project file kept beside a browser edit. */
7547
+ contentType: MediaType | typeof PROJECT_FILE_TYPE;
7547
7548
  }
7549
+ /** Served type of a Pixelorama `.pxo`: a zip the browser never renders. */
7550
+ declare const PROJECT_FILE_TYPE = "application/octet-stream";
7548
7551
  interface GalleryOutput {
7549
7552
  /** Manifest-relative path as recorded (or as the manifest would record it). */
7550
7553
  path: string;
@@ -7671,6 +7674,8 @@ interface GalleryItem {
7671
7674
  */
7672
7675
  edit: GalleryOutput | null;
7673
7676
  editStatus: HandEditStatus | null;
7677
+ /** What an in-browser save recorded beside the edit; null for edits made elsewhere. */
7678
+ editMeta: GalleryEditMeta | null;
7674
7679
  /** Where the provider's own app shows this object, when it has one. */
7675
7680
  upstreamUrl: string | null;
7676
7681
  /** Downloaded work with a durable provider reference; `fetch --refresh` can re-pull it. */
@@ -7786,6 +7791,23 @@ interface BuildGalleryOptions {
7786
7791
  /** Route id for one absolute path: stable across refreshes, not enumerable. */
7787
7792
  declare function galleryMediaId(absolutePath: string): string;
7788
7793
  declare function galleryMediaRoute(id: string): string;
7794
+ /**
7795
+ * Build the gallery from the project's offline state. `specs` are the resolved
7796
+ * (possibly filtered) manifest entries the CLI already computed; lock entries
7797
+ * outside the manifest are added here so paid work is never hidden.
7798
+ */
7799
+ interface GalleryEditMeta {
7800
+ editor: string;
7801
+ savedAt: string;
7802
+ /** sha256 of the generation the edit was based on, or null for untracked art. */
7803
+ basedOn: string | null;
7804
+ /** The edit file changed since the editor saved it (another tool touched it). */
7805
+ changedSince: boolean;
7806
+ /** Manifest-relative path of the layered project file kept beside the edit, if present. */
7807
+ project: string | null;
7808
+ /** Where the page fetches that file to hand it back to the editor; null without one. */
7809
+ projectUrl: string | null;
7810
+ }
7789
7811
  declare function buildGallerySnapshot(opts: BuildGalleryOptions): Promise<GalleryBuild>;
7790
7812
  interface BuildWorkspaceGalleryOptions {
7791
7813
  workspace: Workspace;
@@ -7832,6 +7854,8 @@ interface RenderGalleryOptions {
7832
7854
  editable?: boolean;
7833
7855
  /** Generation jobs are enabled (`--budget`). */
7834
7856
  generation?: boolean;
7857
+ /** The in-browser editor can be installed and served (`--edit` without `--no-editor`). */
7858
+ editor?: boolean;
7835
7859
  }
7836
7860
  declare function renderGallery(snapshot: GallerySnapshot, opts?: RenderGalleryOptions): string;
7837
7861
 
@@ -8248,12 +8272,81 @@ interface GalleryEditHandlerOptions {
8248
8272
  /** The `edit` callback `serveGallery` expects: validate, apply, rebuild. */
8249
8273
  declare function createGalleryEditHandler(opts: GalleryEditHandlerOptions): (body: unknown) => Promise<GalleryBuild>;
8250
8274
 
8275
+ /**
8276
+ * The in-gallery editor is a 46 MB web build that is not part of the npm
8277
+ * package. It is fetched once per pinned release into a user-level cache,
8278
+ * every file verified against the hash the package carries, and served from
8279
+ * there by the gallery. Nothing is executed at install; the browser runs the
8280
+ * wasm, and only from files whose hashes matched.
8281
+ *
8282
+ * A user-level cache rather than the project's `.pixelkiln/`: the pin is per
8283
+ * PixelKiln release, not per project, and one copy serves every project.
8284
+ * `PIXELKILN_TOOLS_DIR` moves it; `PIXELKILN_EDITOR_URL` points downloads at
8285
+ * a mirror or a local directory server for offline machines.
8286
+ */
8287
+ interface EditorInstallStatus {
8288
+ /** Release tag the package pins; null means no build has been published for this version. */
8289
+ release: string | null;
8290
+ dir: string;
8291
+ /** Every pinned file is present with the right hash. */
8292
+ installed: boolean;
8293
+ /** Files still to fetch (missing or hash mismatch). */
8294
+ missing: string[];
8295
+ totalBytes: number;
8296
+ installedBytes: number;
8297
+ }
8298
+ interface EditorInstallProgress {
8299
+ file: string;
8300
+ index: number;
8301
+ count: number;
8302
+ bytes: number;
8303
+ totalBytes: number;
8304
+ /** Bytes fetched so far across all files, including the part of this one. */
8305
+ fetchedBytes: number;
8306
+ /** `start` once per file, `progress` as its bytes arrive, `done` once it verified and landed. */
8307
+ phase: "start" | "progress" | "done";
8308
+ }
8309
+
8310
+ /**
8311
+ * The gallery's side of the in-browser editor: it reports whether the pinned
8312
+ * build is on disk, installs it on request, and serves its files.
8313
+ *
8314
+ * Serving is allowlisted twice. The release tag in the URL must be the one
8315
+ * this package pins, and the file name must be one the pin lists; nothing
8316
+ * else under the tools directory is reachable. A file is served only after
8317
+ * the whole build has verified against the pinned hashes, and its size is
8318
+ * checked again on every read, so a build that changed on disk after
8319
+ * verification is refused rather than served.
8320
+ */
8321
+ interface GalleryEditorStatus extends EditorInstallStatus {
8322
+ pixelorama: string;
8323
+ protocol: number;
8324
+ /** Where the page loads the editor from once installed; null until then. */
8325
+ url: string | null;
8326
+ /** The install in flight, if any. */
8327
+ installing: EditorInstallProgress | null;
8328
+ /** Why the last install failed, until the next attempt. */
8329
+ error: string | null;
8330
+ }
8331
+ interface GalleryEditorHandlers {
8332
+ release: string | null;
8333
+ status(): Promise<GalleryEditorStatus>;
8334
+ /** Start an install unless one is running; returns the status right after. */
8335
+ install(): Promise<GalleryEditorStatus>;
8336
+ /** A verified build file, or null when it is not pinned or not installed. */
8337
+ file(release: string, name: string): Promise<{
8338
+ bytes: Buffer;
8339
+ contentType: string;
8340
+ } | null>;
8341
+ }
8342
+
8251
8343
  /**
8252
8344
  * The gallery's HTTP surface. Unlike the review server this is long-lived:
8253
8345
  * three GET routes, bound to loopback, running until the caller closes it
8254
8346
  * (the CLI does so on Ctrl+C). It has no write path unless the caller opts
8255
- * in: `edit` adds one POST route for manifest edits, and `generate` adds the
8256
- * routes that start a generation job and host its review sheet.
8347
+ * in: `edit` adds one POST route for manifest edits, `generate` adds the
8348
+ * routes that start a generation job and host its review sheet, and `editor`
8349
+ * adds the routes that install and serve the in-browser pixel editor.
8257
8350
  *
8258
8351
  * Every POST is guarded twice, because a page on localhost is reachable by
8259
8352
  * every other page in the browser: the request's Origin must be this server,
@@ -8288,6 +8381,11 @@ interface GalleryServerOptions {
8288
8381
  * sheet. The handlers own budgets and provider access; see `generate.ts`.
8289
8382
  */
8290
8383
  generate?: GalleryGenerateHandlers;
8384
+ /**
8385
+ * Enable `GET /api/editor`, `POST /api/editor/install`, and the static
8386
+ * `/editor/<release>/<file>` routes that serve the pinned editor build.
8387
+ */
8388
+ editor?: GalleryEditorHandlers;
8291
8389
  }
8292
8390
  interface GalleryServer {
8293
8391
  url: string;
package/dist/index.d.ts CHANGED
@@ -7543,8 +7543,11 @@ type GalleryState = PlanState | "undeclared";
7543
7543
  interface GalleryMedia {
7544
7544
  /** Absolute path of the file the server may read for this id. */
7545
7545
  path: string;
7546
- contentType: MediaType;
7546
+ /** Images, or the editor's own project file kept beside a browser edit. */
7547
+ contentType: MediaType | typeof PROJECT_FILE_TYPE;
7547
7548
  }
7549
+ /** Served type of a Pixelorama `.pxo`: a zip the browser never renders. */
7550
+ declare const PROJECT_FILE_TYPE = "application/octet-stream";
7548
7551
  interface GalleryOutput {
7549
7552
  /** Manifest-relative path as recorded (or as the manifest would record it). */
7550
7553
  path: string;
@@ -7671,6 +7674,8 @@ interface GalleryItem {
7671
7674
  */
7672
7675
  edit: GalleryOutput | null;
7673
7676
  editStatus: HandEditStatus | null;
7677
+ /** What an in-browser save recorded beside the edit; null for edits made elsewhere. */
7678
+ editMeta: GalleryEditMeta | null;
7674
7679
  /** Where the provider's own app shows this object, when it has one. */
7675
7680
  upstreamUrl: string | null;
7676
7681
  /** Downloaded work with a durable provider reference; `fetch --refresh` can re-pull it. */
@@ -7786,6 +7791,23 @@ interface BuildGalleryOptions {
7786
7791
  /** Route id for one absolute path: stable across refreshes, not enumerable. */
7787
7792
  declare function galleryMediaId(absolutePath: string): string;
7788
7793
  declare function galleryMediaRoute(id: string): string;
7794
+ /**
7795
+ * Build the gallery from the project's offline state. `specs` are the resolved
7796
+ * (possibly filtered) manifest entries the CLI already computed; lock entries
7797
+ * outside the manifest are added here so paid work is never hidden.
7798
+ */
7799
+ interface GalleryEditMeta {
7800
+ editor: string;
7801
+ savedAt: string;
7802
+ /** sha256 of the generation the edit was based on, or null for untracked art. */
7803
+ basedOn: string | null;
7804
+ /** The edit file changed since the editor saved it (another tool touched it). */
7805
+ changedSince: boolean;
7806
+ /** Manifest-relative path of the layered project file kept beside the edit, if present. */
7807
+ project: string | null;
7808
+ /** Where the page fetches that file to hand it back to the editor; null without one. */
7809
+ projectUrl: string | null;
7810
+ }
7789
7811
  declare function buildGallerySnapshot(opts: BuildGalleryOptions): Promise<GalleryBuild>;
7790
7812
  interface BuildWorkspaceGalleryOptions {
7791
7813
  workspace: Workspace;
@@ -7832,6 +7854,8 @@ interface RenderGalleryOptions {
7832
7854
  editable?: boolean;
7833
7855
  /** Generation jobs are enabled (`--budget`). */
7834
7856
  generation?: boolean;
7857
+ /** The in-browser editor can be installed and served (`--edit` without `--no-editor`). */
7858
+ editor?: boolean;
7835
7859
  }
7836
7860
  declare function renderGallery(snapshot: GallerySnapshot, opts?: RenderGalleryOptions): string;
7837
7861
 
@@ -8248,12 +8272,81 @@ interface GalleryEditHandlerOptions {
8248
8272
  /** The `edit` callback `serveGallery` expects: validate, apply, rebuild. */
8249
8273
  declare function createGalleryEditHandler(opts: GalleryEditHandlerOptions): (body: unknown) => Promise<GalleryBuild>;
8250
8274
 
8275
+ /**
8276
+ * The in-gallery editor is a 46 MB web build that is not part of the npm
8277
+ * package. It is fetched once per pinned release into a user-level cache,
8278
+ * every file verified against the hash the package carries, and served from
8279
+ * there by the gallery. Nothing is executed at install; the browser runs the
8280
+ * wasm, and only from files whose hashes matched.
8281
+ *
8282
+ * A user-level cache rather than the project's `.pixelkiln/`: the pin is per
8283
+ * PixelKiln release, not per project, and one copy serves every project.
8284
+ * `PIXELKILN_TOOLS_DIR` moves it; `PIXELKILN_EDITOR_URL` points downloads at
8285
+ * a mirror or a local directory server for offline machines.
8286
+ */
8287
+ interface EditorInstallStatus {
8288
+ /** Release tag the package pins; null means no build has been published for this version. */
8289
+ release: string | null;
8290
+ dir: string;
8291
+ /** Every pinned file is present with the right hash. */
8292
+ installed: boolean;
8293
+ /** Files still to fetch (missing or hash mismatch). */
8294
+ missing: string[];
8295
+ totalBytes: number;
8296
+ installedBytes: number;
8297
+ }
8298
+ interface EditorInstallProgress {
8299
+ file: string;
8300
+ index: number;
8301
+ count: number;
8302
+ bytes: number;
8303
+ totalBytes: number;
8304
+ /** Bytes fetched so far across all files, including the part of this one. */
8305
+ fetchedBytes: number;
8306
+ /** `start` once per file, `progress` as its bytes arrive, `done` once it verified and landed. */
8307
+ phase: "start" | "progress" | "done";
8308
+ }
8309
+
8310
+ /**
8311
+ * The gallery's side of the in-browser editor: it reports whether the pinned
8312
+ * build is on disk, installs it on request, and serves its files.
8313
+ *
8314
+ * Serving is allowlisted twice. The release tag in the URL must be the one
8315
+ * this package pins, and the file name must be one the pin lists; nothing
8316
+ * else under the tools directory is reachable. A file is served only after
8317
+ * the whole build has verified against the pinned hashes, and its size is
8318
+ * checked again on every read, so a build that changed on disk after
8319
+ * verification is refused rather than served.
8320
+ */
8321
+ interface GalleryEditorStatus extends EditorInstallStatus {
8322
+ pixelorama: string;
8323
+ protocol: number;
8324
+ /** Where the page loads the editor from once installed; null until then. */
8325
+ url: string | null;
8326
+ /** The install in flight, if any. */
8327
+ installing: EditorInstallProgress | null;
8328
+ /** Why the last install failed, until the next attempt. */
8329
+ error: string | null;
8330
+ }
8331
+ interface GalleryEditorHandlers {
8332
+ release: string | null;
8333
+ status(): Promise<GalleryEditorStatus>;
8334
+ /** Start an install unless one is running; returns the status right after. */
8335
+ install(): Promise<GalleryEditorStatus>;
8336
+ /** A verified build file, or null when it is not pinned or not installed. */
8337
+ file(release: string, name: string): Promise<{
8338
+ bytes: Buffer;
8339
+ contentType: string;
8340
+ } | null>;
8341
+ }
8342
+
8251
8343
  /**
8252
8344
  * The gallery's HTTP surface. Unlike the review server this is long-lived:
8253
8345
  * three GET routes, bound to loopback, running until the caller closes it
8254
8346
  * (the CLI does so on Ctrl+C). It has no write path unless the caller opts
8255
- * in: `edit` adds one POST route for manifest edits, and `generate` adds the
8256
- * routes that start a generation job and host its review sheet.
8347
+ * in: `edit` adds one POST route for manifest edits, `generate` adds the
8348
+ * routes that start a generation job and host its review sheet, and `editor`
8349
+ * adds the routes that install and serve the in-browser pixel editor.
8257
8350
  *
8258
8351
  * Every POST is guarded twice, because a page on localhost is reachable by
8259
8352
  * every other page in the browser: the request's Origin must be this server,
@@ -8288,6 +8381,11 @@ interface GalleryServerOptions {
8288
8381
  * sheet. The handlers own budgets and provider access; see `generate.ts`.
8289
8382
  */
8290
8383
  generate?: GalleryGenerateHandlers;
8384
+ /**
8385
+ * Enable `GET /api/editor`, `POST /api/editor/install`, and the static
8386
+ * `/editor/<release>/<file>` routes that serve the pinned editor build.
8387
+ */
8388
+ editor?: GalleryEditorHandlers;
8291
8389
  }
8292
8390
  interface GalleryServer {
8293
8391
  url: string;