@norskvideo/ctl-product-template-schema 0.1.32 → 0.1.34

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 (3) hide show
  1. package/index.d.ts +36 -0
  2. package/index.js +31 -0
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -59,6 +59,10 @@ export declare const ProductTemplateHostTlsSchema: z.ZodObject<{
59
59
  services: z.ZodArray<z.ZodString>;
60
60
  }, z.core.$strip>;
61
61
  export type ProductTemplateHostTls = z.infer<typeof ProductTemplateHostTlsSchema>;
62
+ export declare const ProductTemplateWorkdirSchema: z.ZodObject<{
63
+ services: z.ZodArray<z.ZodString>;
64
+ }, z.core.$strip>;
65
+ export type ProductTemplateWorkdir = z.infer<typeof ProductTemplateWorkdirSchema>;
62
66
  export declare const ProductTemplateAcceleratorSchema: z.ZodEnum<{
63
67
  none: "none";
64
68
  nvidia: "nvidia";
@@ -146,6 +150,16 @@ export declare const ProductTemplateMigrationSchema: z.ZodObject<{
146
150
  }>;
147
151
  }, z.core.$strip>;
148
152
  export type ProductTemplateMigration = z.infer<typeof ProductTemplateMigrationSchema>;
153
+ export declare const PRODUCT_TEMPLATE_WORKLOAD_ROLES: readonly ["viewer", "operator", "builder"];
154
+ export declare const ProductTemplateWorkloadSchema: z.ZodObject<{
155
+ role: z.ZodEnum<{
156
+ viewer: "viewer";
157
+ operator: "operator";
158
+ builder: "builder";
159
+ }>;
160
+ on: z.ZodLiteral<"product">;
161
+ }, z.core.$strip>;
162
+ export type ProductTemplateWorkload = z.infer<typeof ProductTemplateWorkloadSchema>;
149
163
  export declare const ProductTemplateManifestSchema: z.ZodObject<{
150
164
  productTemplateSchemaVersion: z.ZodLiteral<1>;
151
165
  productName: z.ZodString;
@@ -320,9 +334,20 @@ export declare const ProductTemplateManifestSchema: z.ZodObject<{
320
334
  configPath: z.ZodString;
321
335
  }, z.core.$strict>]>>;
322
336
  }, z.core.$strict>>>;
337
+ workdir: z.ZodOptional<z.ZodObject<{
338
+ services: z.ZodArray<z.ZodString>;
339
+ }, z.core.$strip>>;
323
340
  hostTls: z.ZodOptional<z.ZodObject<{
324
341
  services: z.ZodArray<z.ZodString>;
325
342
  }, z.core.$strip>>;
343
+ workload: z.ZodOptional<z.ZodObject<{
344
+ role: z.ZodEnum<{
345
+ viewer: "viewer";
346
+ operator: "operator";
347
+ builder: "builder";
348
+ }>;
349
+ on: z.ZodLiteral<"product">;
350
+ }, z.core.$strip>>;
326
351
  migration: z.ZodOptional<z.ZodObject<{
327
352
  strategy: z.ZodEnum<{
328
353
  overlap: "overlap";
@@ -558,9 +583,20 @@ export declare const ProductTemplateMaterialsSchema: z.ZodObject<{
558
583
  configPath: z.ZodString;
559
584
  }, z.core.$strict>]>>;
560
585
  }, z.core.$strict>>>;
586
+ workdir: z.ZodOptional<z.ZodObject<{
587
+ services: z.ZodArray<z.ZodString>;
588
+ }, z.core.$strip>>;
561
589
  hostTls: z.ZodOptional<z.ZodObject<{
562
590
  services: z.ZodArray<z.ZodString>;
563
591
  }, z.core.$strip>>;
592
+ workload: z.ZodOptional<z.ZodObject<{
593
+ role: z.ZodEnum<{
594
+ viewer: "viewer";
595
+ operator: "operator";
596
+ builder: "builder";
597
+ }>;
598
+ on: z.ZodLiteral<"product">;
599
+ }, z.core.$strip>>;
564
600
  migration: z.ZodOptional<z.ZodObject<{
565
601
  strategy: z.ZodEnum<{
566
602
  overlap: "overlap";
package/index.js CHANGED
@@ -204,6 +204,21 @@ export const ProductTemplateHostTlsSchema = z
204
204
  }),
205
205
  })
206
206
  .meta({ id: "ProductTemplateHostTls", outputId: "ProductTemplateHostTls" });
207
+ // The instance working directory, handed to a product's own services. WHY THIS
208
+ // EXISTS: it is the one per-instance store that survives a relaunch (a named
209
+ // volume does not: relaunch tears down with `down -v`), and the runner mounts
210
+ // it at /data only into media and studio. A product whose own service keeps
211
+ // state -- a relay's state file and site key -- or writes files the engine must
212
+ // read (assets, recordings) needs the same directory at the same path. A
213
+ // product relying on it declares the runner capability `service-workdir`,
214
+ // since an older runner would ignore the field and lose the state.
215
+ export const ProductTemplateWorkdirSchema = z
216
+ .object({
217
+ services: z.array(z.string().min(1)).min(1).meta({
218
+ description: "Compose services that get the instance working directory, read-write at /data -- the same directory, at the same path, that media and studio have -- with NORSK_WORKDIR=/data. Each must be a service in the template's own compose.yml. It survives relaunch, restart and runner upgrade; only `instance delete --purge` removes it.",
219
+ }),
220
+ })
221
+ .meta({ id: "ProductTemplateWorkdir", outputId: "ProductTemplateWorkdir" });
207
222
  // Placement requirements guidance (requirements-authoring.md). Each dimension
208
223
  // the placer reasons over — capacity (vCPUs), cores, GPU, capabilities, host
209
224
  // ports — is optionally declared with a `mode`:
@@ -304,6 +319,16 @@ export const ProductTemplateMigrationSchema = z
304
319
  }),
305
320
  })
306
321
  .meta({ id: "ProductTemplateMigration", outputId: "ProductTemplateMigration" });
322
+ // The roles a template may declare for its instances' workload: at most
323
+ // builder, since registering a template takes builder and that registration is
324
+ // the consent. Built-in names only, whose meaning every host agrees on.
325
+ export const PRODUCT_TEMPLATE_WORKLOAD_ROLES = ["viewer", "operator", "builder"];
326
+ export const ProductTemplateWorkloadSchema = z
327
+ .object({
328
+ role: z.enum(PRODUCT_TEMPLATE_WORKLOAD_ROLES),
329
+ on: z.literal("product"),
330
+ })
331
+ .meta({ id: "ProductTemplateWorkload", outputId: "ProductTemplateWorkload" });
307
332
  export const ProductTemplateManifestSchema = z
308
333
  .object({
309
334
  productTemplateSchemaVersion: z.literal(1),
@@ -350,9 +375,15 @@ export const ProductTemplateManifestSchema = z
350
375
  description: "Host-port bindings whose value rides a product-template parameter. Opt-in per launch via the param value: absent = closed, 'auto' = allocate a free port from `preferred`, number = use it. When opened the port is published as a managed host binding and surfaced to the containers via compose interpolation. Alongside the per-param scalars the runner sets NORSK_ALLOCATED_PORTS: a JSON object keyed by param, each value {port, protocol, service?}, describing every opened port ('{}' when none opted in; unset when nothing is declared) — so a product needing the allocation as data maps one var instead of folding scalars into JSON via interpolation.",
351
376
  }),
352
377
  logs: ProductTemplateLogsSchema.optional(),
378
+ workdir: ProductTemplateWorkdirSchema.optional().meta({
379
+ description: "Mount the instance working directory at /data into the named compose services, as media and studio always have it -- for a product's own service that keeps state across relaunch or shares files with the engine. Absent = not mounted. Declare the runner capability `service-workdir` alongside it.",
380
+ }),
353
381
  hostTls: ProductTemplateHostTlsSchema.optional().meta({
354
382
  description: "Mount the host's TLS certificate and key, read-only, into the named compose services — for a product that serves TLS itself. Copied per launch, so a rotated certificate is picked up on relaunch. Absent = nothing mounted.",
355
383
  }),
384
+ workload: ProductTemplateWorkloadSchema.optional().meta({
385
+ description: "The role each instance's own workload (`urn:norsk:workload:instance:<id>`) holds on its product (`product/<productName>`), granted when it launches, whoever launches it — for an instance that creates or manages its product's other instances (a capture launching recorders). At most `builder`: registering a template takes builder, and that registration is the consent. Absent = the workload holds nothing it was not passed at launch. An older ctl ignores it, and its instances hold nothing.",
386
+ }),
356
387
  migration: ProductTemplateMigrationSchema.optional().meta({
357
388
  description: "How a running instance may be moved between nodes. `strategy` is the strongest promise the product keeps: `overlap` (target started, then source stopped — both may produce briefly), `stopThenStart` (the default when absent — target prepared but not started, source stopped, target started), or `handover` (the job speaks the worker's migration socket and hands over at an exact position). A migrate request may down-grade to a safer strategy but never up-grade past the declaration. Only the manager reads this; the worker never does.",
358
389
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@norskvideo/ctl-product-template-schema",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {