@kindgi/handler 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/README.md CHANGED
@@ -14,7 +14,7 @@ code.
14
14
  | Symbol | Kind | What it is |
15
15
  | --- | --- | --- |
16
16
  | `NodeHandler` | type | `(input: unknown, ctx: NodeContext) => Promise<HandlerResult \| unknown>` |
17
- | `NodeContext` | type | What handlers receive: `runId`, `nodeId`, `tenantId`, `nodeOutputs`, `state`, `abortSignal`, `dryRun`, `principal?`, `authorize`, `can`, `check`, `clockNow`, `waitForToken` |
17
+ | `NodeContext` | type | What handlers receive: `runId`, `nodeId`, `tenantId`, `nodeOutputs`, `state`, `abortSignal`, `dryRun`, `principal?`, `authorize`, `can`, `check`, `clockNow`, `record`, `waitForToken` |
18
18
  | `HandlerResult` | type | Optional structured return — `{ output, stateDelta? }` |
19
19
  | `HandlerRegistry` | type | `ReadonlyMap<NodeId, NodeHandler>` |
20
20
  | `LoopContext` | type | Loop annotation (`loopNodeId`, `iteration`, enclosing-loop `path`) on the journal entries of nodes that ran inside a loop body |
package/dist/types.d.ts CHANGED
@@ -102,8 +102,33 @@ export interface NodeContext {
102
102
  can(action: Action, resource: ResourceRef): Promise<boolean>;
103
103
  /** Full Decision — for advanced cases needing reason/evidence. */
104
104
  check(action: Action, resource: ResourceRef): Promise<Decision>;
105
- /** Read the clock. First call journals `Date.now()`; on replay, returns the journaled value. */
105
+ /**
106
+ * Read the clock, as `record` does: each call journals `Date.now()`.
107
+ * When the step resumes after a wait, its first call returns the time
108
+ * the first call read before, its second the second's, and so on; calls
109
+ * past those read the clock. A retry after a failure reads it afresh.
110
+ * **Determinism:** call it in the same order every time the step runs.
111
+ */
106
112
  clockNow(): Promise<number>;
113
+ /**
114
+ * Decide once for this step. The first call for `key` runs `decide`,
115
+ * journals its result, then returns it. When the step runs again
116
+ * (resumed after a wait, or retried after a failure), the call returns
117
+ * the journaled result and `decide` doesn't run, whatever the data it
118
+ * decided from says now.
119
+ *
120
+ * For a decision the step must keep across a wait: an approval gate's
121
+ * (did the policy ask for a review, under which token), so a policy
122
+ * changed meanwhile can't undo the park or lose the reviewer's answer.
123
+ *
124
+ * - The result is kept as JSON, and returned as JSON the first time too
125
+ * (a `Date` comes back as its string): `decide` returns JSON data.
126
+ * - `undefined` isn't journaled: the next call decides again.
127
+ * - `key` names the decision within the step; a step in a loop body
128
+ * keeps one per iteration. Calls for one key at the same time share
129
+ * one decision.
130
+ */
131
+ record<T>(key: string, decide: () => T | Promise<T>): Promise<T>;
107
132
  /**
108
133
  * Suspend the handler and wait for an external `completeToken(tokenId,
109
134
  * value)`. On first invocation: journals `wait.suspended`, inserts a
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE7D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,CAAC;AAEjG;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE/D;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B;;;;;;;;;OASG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,qEAAqE;IACrE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,kEAAkE;IAClE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChE,gGAAgG;IAChG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAChF;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvF;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM,GAAG,OAAO;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kindgi/handler",
3
- "version": "0.1.0",
4
- "description": "Kindgi™ pack-author authoring surface. The types a pack author writes handlers against: NodeHandler (the function signature), NodeContext (what handlers receive at invocation — run scope, sibling outputs, waitForToken, authorize, clockNow, etc.), HandlerResult (structured return with optional stateDelta), HandlerRegistry (NodeId → NodeHandler map), LoopContext + LoopNodeOutput (loop-node shapes), plus WaitpointCancelledError (thrown by waitForToken when the wait is cancelled externally). Types plus that one error class — no other runtime code. Every runtime that executes Kindgi handlers implements this contract.",
3
+ "version": "0.1.2",
4
+ "description": "Kindgi™ pack-author authoring surface. The types a pack author writes handlers against: NodeHandler (the function signature), NodeContext (what handlers receive at invocation — run scope, sibling outputs, waitForToken, authorize, clockNow, record, etc.), HandlerResult (structured return with optional stateDelta), HandlerRegistry (NodeId → NodeHandler map), LoopContext + LoopNodeOutput (loop-node shapes), plus WaitpointCancelledError (thrown by waitForToken when the wait is cancelled externally). Types plus that one error class — no other runtime code. Every runtime that executes Kindgi handlers implements this contract.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -18,7 +18,8 @@
18
18
  "exports": {
19
19
  ".": {
20
20
  "types": "./dist/index.d.ts",
21
- "import": "./dist/index.js"
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
22
23
  }
23
24
  },
24
25
  "files": [
@@ -27,11 +28,11 @@
27
28
  "README.md"
28
29
  ],
29
30
  "dependencies": {
30
- "@kindgi/authz": "0.1.0",
31
- "@kindgi/types": "0.1.0"
31
+ "@kindgi/authz": "0.1.2",
32
+ "@kindgi/types": "0.1.2"
32
33
  },
33
34
  "engines": {
34
- "node": ">=22.0.0"
35
+ "node": ">=22.12.0"
35
36
  },
36
37
  "publishConfig": {
37
38
  "access": "public",
package/src/types.ts CHANGED
@@ -109,8 +109,33 @@ export interface NodeContext {
109
109
  can(action: Action, resource: ResourceRef): Promise<boolean>;
110
110
  /** Full Decision — for advanced cases needing reason/evidence. */
111
111
  check(action: Action, resource: ResourceRef): Promise<Decision>;
112
- /** Read the clock. First call journals `Date.now()`; on replay, returns the journaled value. */
112
+ /**
113
+ * Read the clock, as `record` does: each call journals `Date.now()`.
114
+ * When the step resumes after a wait, its first call returns the time
115
+ * the first call read before, its second the second's, and so on; calls
116
+ * past those read the clock. A retry after a failure reads it afresh.
117
+ * **Determinism:** call it in the same order every time the step runs.
118
+ */
113
119
  clockNow(): Promise<number>;
120
+ /**
121
+ * Decide once for this step. The first call for `key` runs `decide`,
122
+ * journals its result, then returns it. When the step runs again
123
+ * (resumed after a wait, or retried after a failure), the call returns
124
+ * the journaled result and `decide` doesn't run, whatever the data it
125
+ * decided from says now.
126
+ *
127
+ * For a decision the step must keep across a wait: an approval gate's
128
+ * (did the policy ask for a review, under which token), so a policy
129
+ * changed meanwhile can't undo the park or lose the reviewer's answer.
130
+ *
131
+ * - The result is kept as JSON, and returned as JSON the first time too
132
+ * (a `Date` comes back as its string): `decide` returns JSON data.
133
+ * - `undefined` isn't journaled: the next call decides again.
134
+ * - `key` names the decision within the step; a step in a loop body
135
+ * keeps one per iteration. Calls for one key at the same time share
136
+ * one decision.
137
+ */
138
+ record<T>(key: string, decide: () => T | Promise<T>): Promise<T>;
114
139
  /**
115
140
  * Suspend the handler and wait for an external `completeToken(tokenId,
116
141
  * value)`. On first invocation: journals `wait.suspended`, inserts a