@intentius/chant-lexicon-fly 0.93.0 → 0.95.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/integrity.json +3 -3
- package/dist/manifest.json +1 -1
- package/dist/op/activities/box-services.d.ts +40 -0
- package/dist/op/activities/box-services.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +5 -3
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/sprite-config.d.ts +54 -3
- package/dist/op/activities/sprite-config.d.ts.map +1 -1
- package/dist/op/activities/sprite-service-converge.d.ts +24 -1
- package/dist/op/activities/sprite-service-converge.d.ts.map +1 -1
- package/dist/op/activities/sprite-services.d.ts +2 -2
- package/dist/op/activities/sprites.d.ts +1 -1
- package/dist/op/activity-contracts.d.ts +33 -3
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/builders.d.ts +7 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/skills/chant-fly-sprites.md +4 -4
- package/package.json +2 -2
- package/src/op/activities/box-services.ts +78 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/sprite-box-services.test.ts +318 -0
- package/src/op/activities/sprite-config.ts +214 -4
- package/src/op/activities/sprite-service-converge.ts +31 -3
- package/src/op/activities/sprite-services.ts +2 -2
- package/src/op/activities/sprites.ts +1 -1
- package/src/op/activity-contracts.test.ts +19 -2
- package/src/op/activity-contracts.ts +37 -3
- package/src/op/builders.ts +7 -1
- package/src/skills/chant-fly-sprites.md +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sprite Services activities (#2711) — imperative create/get/list/start/stop/
|
|
3
|
-
* delete/logs over a Sprite's background services, the surface a box's door
|
|
4
|
-
*
|
|
3
|
+
* delete/logs over a Sprite's background services, the surface a box's door
|
|
4
|
+
* and hud run as long-lived services through (`sprite-env services`
|
|
5
5
|
* inside the sprite, `/v1/sprites/{id}/services/...` outside). Shared by the
|
|
6
6
|
* Sprites API, wisp (arugula-salad/wisp) and spritzer 0.6.0's container mode
|
|
7
7
|
* (INTENTIUS/spritzer#22).
|
|
@@ -630,7 +630,7 @@ export interface SpriteUrlResult {
|
|
|
630
630
|
* nothing until now exposed it on its own (for a later phase that only has
|
|
631
631
|
* the sprite `id`) or waited on it. `GET /v1/sprites/{id}` for the URL; with
|
|
632
632
|
* `path` set, polls `GET {url}{path}` until `status` (default any 2xx) or
|
|
633
|
-
* `timeoutMs` runs out — the box's door/hud
|
|
633
|
+
* `timeoutMs` runs out — the box's door/hud services take a moment to
|
|
634
634
|
* bind their `http_port` after `spriteServiceStart`.
|
|
635
635
|
*/
|
|
636
636
|
export async function spriteUrl(
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "@intentius/chant/op";
|
|
14
14
|
import * as contracts from "./activity-contracts";
|
|
15
15
|
import * as activities from "./activities";
|
|
16
|
-
import { spriteServicesObserve, spriteServiceRestart } from "./builders";
|
|
16
|
+
import { spriteApplyServices, spriteServicesObserve, spriteServiceRestart } from "./builders";
|
|
17
17
|
|
|
18
18
|
const CONTRACTS: Map<string, ActivityContract> = new Map(
|
|
19
19
|
Object.values(contracts).filter(isActivityContract).map((c) => [c.name, c]),
|
|
@@ -29,7 +29,7 @@ describe("fly activity contracts (#2843)", () => {
|
|
|
29
29
|
expect(typeof (activities as unknown as Record<string, unknown>)[c.name], `${c.name} is not an exported activity`).toBe("function");
|
|
30
30
|
expect(c.returns, `${c.name} declares no return schema`).toBeDefined();
|
|
31
31
|
}
|
|
32
|
-
expect([...CONTRACTS.keys()].sort()).toEqual(["spriteServiceRestart", "spriteServicesObserve"]);
|
|
32
|
+
expect([...CONTRACTS.keys()].sort()).toEqual(["spriteApplyServices", "spriteServiceRestart", "spriteServicesObserve"]);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
test("a ConvergeOp observing spriteServicesObserve passes OPS012 and OPS013 (the guide's example)", () => {
|
|
@@ -63,9 +63,26 @@ describe("fly activity contracts (#2843)", () => {
|
|
|
63
63
|
expect(issues.some((i) => i.message.includes("servicefile"))).toBe(true);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
test("the box forms validate: observe and restart with box: true, and an apply with box, only, start and restart (#2880)", () => {
|
|
67
|
+
const { op: converge } = ConvergeOp({
|
|
68
|
+
name: "converge",
|
|
69
|
+
env: "box",
|
|
70
|
+
observe: spriteServicesObserve({ box: true }),
|
|
71
|
+
rules: [when<ResourceSymptom>(eq("status", "drifted"), run("restart-service"), { id: "restart-drifted", why: "restart it" })],
|
|
72
|
+
});
|
|
73
|
+
expect(validateActivitySteps(converge.props as never, CONTRACTS)).toEqual([]);
|
|
74
|
+
expect(validateStepOutputRefs(converge.props as never, CONTRACTS)).toEqual([]);
|
|
75
|
+
expect(validateActivitySteps(op([spriteServiceRestart({ box: true })]), CONTRACTS)).toEqual([]);
|
|
76
|
+
expect(validateActivitySteps(op([spriteApplyServices({ box: true, only: ["site"], start: true, restart: true })]), CONTRACTS)).toEqual([]);
|
|
77
|
+
expect(validateActivitySteps(op([spriteApplyServices({ id: "box-1", services: [{ name: "app", cmd: "node app.js", needs: [] }], start: true })]), CONTRACTS)).toEqual([]);
|
|
78
|
+
const issues = validateActivitySteps(op([{ kind: "activity", fn: "spriteApplyServices", args: { box: true, onlyy: ["site"] } }]), CONTRACTS);
|
|
79
|
+
expect(issues.some((i) => i.message.includes("onlyy"))).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
|
|
66
82
|
test("loadActivityContracts finds them at @intentius/chant-lexicon-fly/op/activity-contracts", async () => {
|
|
67
83
|
const loaded = await loadActivityContracts(["fly"]);
|
|
68
84
|
expect(loaded.get("spriteServicesObserve")?.returns).toBeDefined();
|
|
69
85
|
expect(loaded.get("spriteServiceRestart")?.returns).toBeDefined();
|
|
86
|
+
expect(loaded.get("spriteApplyServices")?.returns).toBeDefined();
|
|
70
87
|
});
|
|
71
88
|
});
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
* needs its return schema; without one, every project declaring such a
|
|
13
13
|
* ConvergeOp failed `chant build` and `chant lint`. `spriteServiceRestart` is
|
|
14
14
|
* the step of the Op such a ConvergeOp's rule runs, and its result is what a
|
|
15
|
-
* later step would read.
|
|
15
|
+
* later step would read. `spriteApplyServices` is covered for its box form
|
|
16
|
+
* (#2880): `box`, `only`, `start` and `restart`, and the per-service actions
|
|
17
|
+
* its result names. The other Sprites activities have no contract yet,
|
|
16
18
|
* which OPS012 skips rather than flags.
|
|
17
19
|
*
|
|
18
20
|
* Each `args` schema mirrors the `*Args` interface in
|
|
19
|
-
* `./activities/sprite-service-converge.ts`
|
|
20
|
-
* `*Result`. Authored with `z.strictObject(...)`, so a misspelled key fails
|
|
21
|
+
* `./activities/sprite-service-converge.ts` or `./activities/sprite-config.ts`
|
|
22
|
+
* and each `returns` schema the `*Result`. Authored with `z.strictObject(...)`, so a misspelled key fails
|
|
21
23
|
* the build instead of vanishing.
|
|
22
24
|
*/
|
|
23
25
|
|
|
@@ -44,6 +46,7 @@ export const spriteServicesObserveContract = activityContract(
|
|
|
44
46
|
...via,
|
|
45
47
|
services: z.array(declaredService).optional(),
|
|
46
48
|
servicesFile: z.string().optional(),
|
|
49
|
+
box: z.boolean().optional(),
|
|
47
50
|
probes: z.number().optional(),
|
|
48
51
|
probeIntervalMs: z.number().optional(),
|
|
49
52
|
}),
|
|
@@ -61,7 +64,38 @@ export const spriteServiceRestartContract = activityContract(
|
|
|
61
64
|
health: z.string().optional(),
|
|
62
65
|
services: z.array(declaredService).optional(),
|
|
63
66
|
servicesFile: z.string().optional(),
|
|
67
|
+
box: z.boolean().optional(),
|
|
64
68
|
waitMs: z.number().optional(),
|
|
65
69
|
}),
|
|
66
70
|
z.object({ name: z.string(), healthy: z.boolean().nullable() }),
|
|
67
71
|
);
|
|
72
|
+
|
|
73
|
+
const serviceSpec = z.strictObject({
|
|
74
|
+
name: z.string(),
|
|
75
|
+
cmd: z.string(),
|
|
76
|
+
args: z.array(z.string()).optional(),
|
|
77
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
78
|
+
dir: z.string().optional(),
|
|
79
|
+
needs: z.array(z.string()).optional(),
|
|
80
|
+
http_port: z.number().optional(),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export const spriteApplyServicesContract = activityContract(
|
|
84
|
+
"spriteApplyServices",
|
|
85
|
+
z.strictObject({
|
|
86
|
+
id: z.string().optional(),
|
|
87
|
+
services: z.array(serviceSpec).optional(),
|
|
88
|
+
box: z.boolean().optional(),
|
|
89
|
+
only: z.array(z.string()).optional(),
|
|
90
|
+
start: z.boolean().optional(),
|
|
91
|
+
restart: z.boolean().optional(),
|
|
92
|
+
spriteEnv: z.string().optional(),
|
|
93
|
+
endpoint: z.string().optional(),
|
|
94
|
+
token: z.string().optional(),
|
|
95
|
+
}),
|
|
96
|
+
z.object({
|
|
97
|
+
applied: z.array(z.string()),
|
|
98
|
+
started: z.array(z.string()),
|
|
99
|
+
services: z.array(z.object({ name: z.string(), action: z.enum(["created", "replaced", "restarted", "started", "left"]) })).optional(),
|
|
100
|
+
}),
|
|
101
|
+
);
|
package/src/op/builders.ts
CHANGED
|
@@ -108,7 +108,13 @@ export const spriteListDir = spriteStep<SpriteListDirArgs>("spriteListDir", "fas
|
|
|
108
108
|
export const spriteRemove = spriteStep<SpriteRemoveArgs>("spriteRemove", "fastIdempotent");
|
|
109
109
|
/** Reconcile a sprite's outbound network policy — the fully typed twin of core's `spriteApplyNetworkPolicy`. Defaults to the `fastIdempotent` profile. */
|
|
110
110
|
export const spriteApplyNetworkPolicy = spriteStep<SpriteApplyNetworkPolicyArgs>("spriteApplyNetworkPolicy", "fastIdempotent");
|
|
111
|
-
/**
|
|
111
|
+
/**
|
|
112
|
+
* Reconcile a sprite's background services — the fully typed twin of core's
|
|
113
|
+
* `spriteApplyServices`. With an `id`, through the Sprites API; without one,
|
|
114
|
+
* inside the sprite through sprite-env, applying the box block's services
|
|
115
|
+
* (`box: true`, with `only`, `start` and `restart`, #2880). Defaults to the
|
|
116
|
+
* `fastIdempotent` profile.
|
|
117
|
+
*/
|
|
112
118
|
export const spriteApplyServices = spriteStep<SpriteApplyServicesArgs>("spriteApplyServices", "fastIdempotent");
|
|
113
119
|
/** Create-and-start one background service (#2711) — the single-service primitive underneath `spriteApplyServices`. Defaults to the `longInfra` profile (the create+start NDJSON round trip). */
|
|
114
120
|
export const spriteServiceCreate = spriteStep<SpriteServiceCreateArgs>("spriteServiceCreate", "longInfra");
|
|
@@ -104,13 +104,13 @@ The same lexicon ships more Sprite primitives, all imported from `@intentius/cha
|
|
|
104
104
|
| Family | Activities | Use |
|
|
105
105
|
|--------|-----------|-----|
|
|
106
106
|
| Filesystem (#848) | `spriteWriteFile` / `spriteReadFile` / `spriteListDir` / `spriteRemove` | stage an input file and read a result out without shelling `spriteExec` + `cat` |
|
|
107
|
-
| Config reconcile (#849) | `spriteApplyNetworkPolicy` / `spriteApplyServices` | reconcile a Sprite's egress allowlist and background services against typed config (validated before any HTTP; a whole-object replace for policy, create-or-update by name for services) |
|
|
108
|
-
| Services (#2711) | `spriteServiceCreate` / `spriteServiceGet` / `spriteServiceList` / `spriteServiceStart` / `spriteServiceStop` / `spriteServiceDelete` / `spriteServiceLogs` | the single-service primitives underneath `spriteApplyServices` — create-and-start one long-lived service (a box's door
|
|
109
|
-
| Converge (#2778) | `spriteServicesObserve` / `spriteServiceRestart` | keep a box's declared services running with a `ConvergeOp`: the observer step gives one verdict per service (`in-sync`, `drifted`, `unknown`) from the supervisor and each health URL, and the restart is the step of the Op a rule dispatches for the drifted service. Inside the sprite they call `sprite-env services`; with a sprite `id` they use the API |
|
|
107
|
+
| Config reconcile (#849) | `spriteApplyNetworkPolicy` / `spriteApplyServices` | reconcile a Sprite's egress allowlist and background services against typed config (validated before any HTTP; a whole-object replace for policy, create-or-update by name for services). Without an `id`, `spriteApplyServices({ box: true })` runs inside the sprite and applies the box block's `services` through `sprite-env services` (#2880): it creates the missing ones and deletes and creates the changed ones, in dependency order, with `only`, `start` and `restart` |
|
|
108
|
+
| Services (#2711) | `spriteServiceCreate` / `spriteServiceGet` / `spriteServiceList` / `spriteServiceStart` / `spriteServiceStop` / `spriteServiceDelete` / `spriteServiceLogs` | the single-service primitives underneath `spriteApplyServices` — create-and-start one long-lived service (a box's door or hud), inspect or list what's running, stop/start or delete one by name, read its log tail |
|
|
109
|
+
| Converge (#2778) | `spriteServicesObserve` / `spriteServiceRestart` | keep a box's declared services running with a `ConvergeOp`: the observer step gives one verdict per service (`in-sync`, `drifted`, `unknown`) from the supervisor and each health URL, and the restart is the step of the Op a rule dispatches for the drifted service. Inside the sprite they call `sprite-env services`; with a sprite `id` they use the API. The services come from `services`, a `servicesFile`, or with `box: true` the box block's `services` in `chant.workspace.json` (#2880) |
|
|
110
110
|
| Sprite URL / delete (#2711) | `spriteUrl` / `spriteDelete` | resolve a Sprite's URL, optionally waiting until a path on it answers; delete the Sprite (`spriteDelete` is `spriteDestroy` under the name spritzer/wisp and the other lexicons' delete activities use — same call, either name) |
|
|
111
111
|
| Keep-alive (#847) | `spriteTaskCreate` / `spriteTaskRefresh` / `spriteTaskRelease` | hold a Sprite active for a session so it will not pause; a session past the 1-hour task cap refreshes on an interval |
|
|
112
112
|
|
|
113
|
-
These are still runtime-orchestration primitives, not declarable resources — a Sprite has no desired-state create body to reconcile. Services created directly with `spriteServiceCreate` are what a box's `spritzer` preset provisions door/hud
|
|
113
|
+
These are still runtime-orchestration primitives, not declarable resources — a Sprite has no desired-state create body to reconcile. Services created directly with `spriteServiceCreate` are what a box's `spritzer` preset provisions door/hud on (arugula-salad/studio#27) — the same wire surface as `sprite-env services` inside the sprite, spritzer 0.6.0's container mode, and wisp.
|
|
114
114
|
|
|
115
115
|
## Where it fits
|
|
116
116
|
|