@norskvideo/ctl-product-template-schema 0.1.0 → 0.1.2

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/index.d.ts CHANGED
@@ -20,6 +20,12 @@ export declare const ProductTemplateAdvancedSchema: z.ZodObject<{
20
20
  hostPorts: z.ZodOptional<z.ZodObject<{
21
21
  default: z.ZodOptional<z.ZodArray<z.ZodString>>;
22
22
  }, z.core.$strip>>;
23
+ shmSize: z.ZodOptional<z.ZodObject<{
24
+ default: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>>;
26
+ shmGroup: z.ZodOptional<z.ZodObject<{
27
+ default: z.ZodOptional<z.ZodString>;
28
+ }, z.core.$strip>>;
23
29
  }, z.core.$strip>;
24
30
  export declare const ProductTemplateAllocatedPortSchema: z.ZodObject<{
25
31
  param: z.ZodString;
@@ -69,6 +75,12 @@ export declare const ProductTemplateManifestSchema: z.ZodObject<{
69
75
  hostPorts: z.ZodOptional<z.ZodObject<{
70
76
  default: z.ZodOptional<z.ZodArray<z.ZodString>>;
71
77
  }, z.core.$strip>>;
78
+ shmSize: z.ZodOptional<z.ZodObject<{
79
+ default: z.ZodOptional<z.ZodString>;
80
+ }, z.core.$strip>>;
81
+ shmGroup: z.ZodOptional<z.ZodObject<{
82
+ default: z.ZodOptional<z.ZodString>;
83
+ }, z.core.$strip>>;
72
84
  }, z.core.$strip>>;
73
85
  allocatedPorts: z.ZodOptional<z.ZodArray<z.ZodObject<{
74
86
  param: z.ZodString;
@@ -167,6 +179,12 @@ export declare const ProductTemplateMaterialsSchema: z.ZodObject<{
167
179
  hostPorts: z.ZodOptional<z.ZodObject<{
168
180
  default: z.ZodOptional<z.ZodArray<z.ZodString>>;
169
181
  }, z.core.$strip>>;
182
+ shmSize: z.ZodOptional<z.ZodObject<{
183
+ default: z.ZodOptional<z.ZodString>;
184
+ }, z.core.$strip>>;
185
+ shmGroup: z.ZodOptional<z.ZodObject<{
186
+ default: z.ZodOptional<z.ZodString>;
187
+ }, z.core.$strip>>;
170
188
  }, z.core.$strip>>;
171
189
  allocatedPorts: z.ZodOptional<z.ZodArray<z.ZodObject<{
172
190
  param: z.ZodString;
package/index.js CHANGED
@@ -73,6 +73,16 @@ export const ProductTemplateAdvancedSchema = z
73
73
  // exclusive and a second instance needs a different one. Hard pinning is
74
74
  // a future product-template-pins concern, not this knob.
75
75
  hostPorts: z.object({ default: z.array(z.string()).optional() }).optional(),
76
+ // Shared memory. `shmSize` sizes media's private /dev/shm — or, under a
77
+ // group, the shared IPC namespace every member of that group joins.
78
+ // `shmGroup` opts the instance out of privacy altogether and into a named
79
+ // namespace shared with every other member on the host — what a zero-copy
80
+ // cross-instance transport (MXL) needs, and meaningless without one. A
81
+ // product that requires the shared namespace supplies the group name as its
82
+ // `default`, so an operator gets it without knowing the transport's
83
+ // mechanics.
84
+ shmSize: z.object({ default: z.string().optional() }).optional(),
85
+ shmGroup: z.object({ default: z.string().optional() }).optional(),
76
86
  })
77
87
  .meta({ id: "ProductTemplateAdvanced", outputId: "ProductTemplateAdvanced" });
78
88
  // A host-port binding whose value rides a product-template parameter, opted in per
@@ -117,7 +127,7 @@ export const ProductTemplateManifestSchema = z
117
127
  description: "Settings-backed runner knobs the operator may override per instance. Key presence opts the knob into the launch form; `default` pre-fills it (else the runner's daemon-wide default applies).",
118
128
  }),
119
129
  allocatedPorts: z.array(ProductTemplateAllocatedPortSchema).optional().meta({
120
- 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.",
130
+ 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.",
121
131
  }),
122
132
  })
123
133
  .meta({ id: "ProductTemplateManifest", outputId: "ProductTemplateManifest" });
@@ -181,7 +191,8 @@ const ProductTemplateFileSchema = z.object({
181
191
  // accepts both via the same union.
182
192
  content: z.union([z.string(), z.instanceof(Uint8Array)]),
183
193
  });
184
- // In-memory bundle the producer builds; the tar packer turns this into bytes.
194
+ // In-memory bundle the producer builds; packProductTemplate (the `./pack`
195
+ // subpath) turns this into tar bytes at the paths below.
185
196
  //
186
197
  // `workflow`, `components` and `dashboards` are known top-level paths in the
187
198
  // v1 tar format. The runner detects studio in the compose stack and mounts
package/pack.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { type TarEntry } from "@norskvideo/ctl-foundation/browser";
2
+ import type { ProductTemplateMaterials } from "./index.js";
3
+ export declare function productTemplateTarEntries(materials: ProductTemplateMaterials): TarEntry[];
4
+ /** `mtime` stamps every tar entry's header with a fixed modification time.
5
+ * Pass it (alongside a fixed manifest `generatedAt`) for a reproducible
6
+ * build — without it packTar defaults each entry to the wall clock, so the
7
+ * bytes differ run to run. */
8
+ export declare function packProductTemplate(materials: ProductTemplateMaterials, mtime?: Date): Uint8Array;
package/pack.js ADDED
@@ -0,0 +1,48 @@
1
+ // The producer half of the product-template wire format: materials -> tar
2
+ // entries -> tar bytes, at the v1 paths documented on
3
+ // ProductTemplateMaterialsSchema in index.ts. Every product repo used to carry
4
+ // its own copy of this layout and the copies drifted (several silently dropped
5
+ // workdir-seed/); this is the single source. The runner consumes the same
6
+ // paths on the reader side (manifest.json / parameters.yaml / compose.yml
7
+ // validation, workflow.yml + components/ + dashboards/ mounts, workdir-seed/
8
+ // launch copy), so layout changes here are contract changes — additive only.
9
+ //
10
+ // Browser-safe: foundation's packTar and the yaml stringifier are both pure.
11
+ import { packTar } from "@norskvideo/ctl-foundation/browser";
12
+ import { stringify as yamlStringify } from "yaml";
13
+ export function productTemplateTarEntries(materials) {
14
+ const entries = [
15
+ { name: "manifest.json", content: `${JSON.stringify(materials.manifest, null, 2)}\n` },
16
+ { name: "compose.yml", content: materials.composeYaml },
17
+ ];
18
+ if (materials.workflow !== undefined) {
19
+ entries.push({ name: "workflow.yml", content: materials.workflow });
20
+ }
21
+ if (materials.parameters) {
22
+ entries.push({
23
+ name: "parameters.yaml",
24
+ content: yamlStringify(materials.parameters, { aliasDuplicateObjects: false }),
25
+ });
26
+ }
27
+ for (const c of materials.components) {
28
+ entries.push({ name: `components/${c.path}`, content: c.content });
29
+ }
30
+ for (const d of materials.dashboards) {
31
+ entries.push({ name: `dashboards/${d.path}`, content: d.content });
32
+ }
33
+ for (const a of materials.assets) {
34
+ entries.push({ name: `assets/${a.path}`, content: a.content });
35
+ }
36
+ for (const s of materials.workdirSeed) {
37
+ entries.push({ name: `workdir-seed/${s.path}`, content: s.content });
38
+ }
39
+ return entries;
40
+ }
41
+ /** `mtime` stamps every tar entry's header with a fixed modification time.
42
+ * Pass it (alongside a fixed manifest `generatedAt`) for a reproducible
43
+ * build — without it packTar defaults each entry to the wall clock, so the
44
+ * bytes differ run to run. */
45
+ export function packProductTemplate(materials, mtime) {
46
+ const entries = productTemplateTarEntries(materials);
47
+ return packTar(mtime ? entries.map((e) => ({ ...e, mtime })) : entries);
48
+ }
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@norskvideo/ctl-product-template-schema",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./index.d.ts",
8
8
  "default": "./index.js"
9
9
  },
10
+ "./pack": {
11
+ "types": "./pack.d.ts",
12
+ "default": "./pack.js"
13
+ },
10
14
  "./params": {
11
15
  "types": "./params.d.ts",
12
16
  "default": "./params.js"
@@ -15,6 +19,8 @@
15
19
  "main": "./index.js",
16
20
  "types": "./index.d.ts",
17
21
  "dependencies": {
22
+ "@norskvideo/ctl-foundation": "^0.1.0",
23
+ "yaml": "^2.8.0",
18
24
  "zod": "^4.3.6"
19
25
  },
20
26
  "publishConfig": {