@alpacakit/core 0.1.0-beta.19

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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -0
  3. package/dist/adapters/fs-layered-asset-source.d.ts +12 -0
  4. package/dist/adapters/fs-layered-asset-source.d.ts.map +1 -0
  5. package/dist/adapters/fs-layered-asset-source.js +170 -0
  6. package/dist/adapters/index.d.ts +2 -0
  7. package/dist/adapters/index.d.ts.map +1 -0
  8. package/dist/adapters/index.js +1 -0
  9. package/dist/branding.d.ts +2 -0
  10. package/dist/branding.d.ts.map +1 -0
  11. package/dist/branding.js +1 -0
  12. package/dist/decode-result.d.ts +13 -0
  13. package/dist/decode-result.d.ts.map +1 -0
  14. package/dist/decode-result.js +23 -0
  15. package/dist/defaults.d.ts +6 -0
  16. package/dist/defaults.d.ts.map +1 -0
  17. package/dist/defaults.js +5 -0
  18. package/dist/definition.d.ts +35 -0
  19. package/dist/definition.d.ts.map +1 -0
  20. package/dist/definition.js +24 -0
  21. package/dist/factory.d.ts +16 -0
  22. package/dist/factory.d.ts.map +1 -0
  23. package/dist/factory.js +18 -0
  24. package/dist/ids.d.ts +15 -0
  25. package/dist/ids.d.ts.map +1 -0
  26. package/dist/ids.js +24 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +13 -0
  30. package/dist/mutation.d.ts +11 -0
  31. package/dist/mutation.d.ts.map +1 -0
  32. package/dist/mutation.js +32 -0
  33. package/dist/pipeline.d.ts +12 -0
  34. package/dist/pipeline.d.ts.map +1 -0
  35. package/dist/pipeline.js +16 -0
  36. package/dist/ports.d.ts +91 -0
  37. package/dist/ports.d.ts.map +1 -0
  38. package/dist/ports.js +16 -0
  39. package/dist/registry.d.ts +30 -0
  40. package/dist/registry.d.ts.map +1 -0
  41. package/dist/registry.js +85 -0
  42. package/dist/schema.d.ts +14 -0
  43. package/dist/schema.d.ts.map +1 -0
  44. package/dist/schema.js +57 -0
  45. package/dist/types.d.ts +23 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +1 -0
  48. package/package.json +37 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Masahiro Tonomura (codemafia0000)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # @alpacakit/core
2
+
3
+ Architecture-neutral kernel primitives shared by the AlpacaLoop workspace
4
+ packages and the `alpacaloop` control plane: branded ids, port interfaces
5
+ (registry, resolver, adapter, reducer, projector, pipeline, runtime codec),
6
+ map/keyed registries, sequential pipelines, zod schema helpers and codecs,
7
+ defaulted model factories, and immer-based immutable mutation helpers.
8
+
9
+ This package is published together with the root `alpacaloop` package and
10
+ `@alpacakit/plan-graph` (which depends on it). Its zod and immer coupling
11
+ is deliberate: schema helpers and mutation helpers are part of the public
12
+ API, so both libraries are pinned runtime dependencies.
13
+
14
+ Main exports: `createMapRegistry` / `createKeyedRegistry`,
15
+ `createOrderedResolver`, `createSequentialPipeline`,
16
+ `createSchemaRuntimeCodec` and the `schema.ts` helpers, `makeBrandedId` /
17
+ id factories, `produceImmutable` and the draft mutation helpers, and the
18
+ shared empty-value defaults.
@@ -0,0 +1,12 @@
1
+ import { type AssetLayer, type AssetSourceDiagnostic, type LayeredAssetSource, type LoadedAsset } from "../ports.js";
2
+ export declare class FsLayeredAssetSource implements LayeredAssetSource {
3
+ private readonly layers;
4
+ private loaded;
5
+ private currentDiagnostics;
6
+ constructor(layers: readonly AssetLayer[]);
7
+ list(): Promise<readonly LoadedAsset[]>;
8
+ get(assetPath: string): Promise<LoadedAsset | null>;
9
+ diagnostics(): readonly AssetSourceDiagnostic[];
10
+ private load;
11
+ }
12
+ //# sourceMappingURL=fs-layered-asset-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-layered-asset-source.d.ts","sourceRoot":"","sources":["../../src/adapters/fs-layered-asset-source.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,UAAU,EAEf,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAsBrB,qBAAa,oBAAqB,YAAW,kBAAkB;IAIjD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,MAAM,CAAgD;IAC9D,OAAO,CAAC,kBAAkB,CAAwC;gBAErC,MAAM,EAAE,SAAS,UAAU,EAAE;IAE1D,IAAI,IAAI,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC;IAKjC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAOzD,WAAW,IAAI,SAAS,qBAAqB,EAAE;YAIjC,IAAI;CA4CnB"}
@@ -0,0 +1,170 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { ASSET_LAYER_KIND, ASSET_SOURCE_DIAGNOSTIC_KIND, LOADED_ASSET_SOURCE, } from "../ports.js";
5
+ const FRONTMATTER_DELIMITER = "---";
6
+ const SYSTEM_EJECTED_DIRECTORY = "__system";
7
+ const LOADED_ASSET_SOURCE_BY_LAYER_KIND = {
8
+ [ASSET_LAYER_KIND.repository]: LOADED_ASSET_SOURCE.repository,
9
+ [ASSET_LAYER_KIND.packagedSystem]: LOADED_ASSET_SOURCE.packagedSystem,
10
+ };
11
+ export class FsLayeredAssetSource {
12
+ layers;
13
+ loaded = null;
14
+ currentDiagnostics = [];
15
+ constructor(layers) {
16
+ this.layers = layers;
17
+ }
18
+ list() {
19
+ this.loaded ??= this.load();
20
+ return this.loaded;
21
+ }
22
+ async get(assetPath) {
23
+ const normalized = normalizeAssetPath(assetPath);
24
+ return ((await this.list()).find((asset) => asset.path === normalized) ?? null);
25
+ }
26
+ diagnostics() {
27
+ return this.currentDiagnostics;
28
+ }
29
+ async load() {
30
+ const diagnostics = [];
31
+ const discoveredByKindAndPath = new Map();
32
+ const selectedByPath = new Map();
33
+ for (const layer of this.layers) {
34
+ for (const asset of await discoverLayer(layer)) {
35
+ const kindPathKey = `${layer.kind}\0${asset.path}`;
36
+ const group = discoveredByKindAndPath.get(kindPathKey);
37
+ if (group === undefined) {
38
+ discoveredByKindAndPath.set(kindPathKey, {
39
+ first: asset,
40
+ roots: new Set([layer.root]),
41
+ });
42
+ }
43
+ else {
44
+ group.roots.add(layer.root);
45
+ }
46
+ if (!selectedByPath.has(asset.path)) {
47
+ selectedByPath.set(asset.path, asset);
48
+ }
49
+ }
50
+ }
51
+ for (const group of discoveredByKindAndPath.values()) {
52
+ const roots = duplicateRoots(group.roots);
53
+ if (roots === null) {
54
+ continue;
55
+ }
56
+ diagnostics.push({
57
+ kind: ASSET_SOURCE_DIAGNOSTIC_KIND.duplicateInLayer,
58
+ path: group.first.path,
59
+ layerKind: group.first.layer.kind,
60
+ roots,
61
+ });
62
+ }
63
+ const assets = await Promise.all([...selectedByPath.values()]
64
+ .sort((left, right) => left.path.localeCompare(right.path))
65
+ .map(loadAsset));
66
+ this.currentDiagnostics = diagnostics.sort(compareDiagnostics);
67
+ return assets;
68
+ }
69
+ }
70
+ function duplicateRoots(roots) {
71
+ const [first, second, ...remaining] = roots;
72
+ return first === undefined || second === undefined
73
+ ? null
74
+ : [first, second, ...remaining];
75
+ }
76
+ async function discoverLayer(layer) {
77
+ const paths = await discoverFilePaths(layer.root, layer.root);
78
+ return paths.map((filePath) => ({
79
+ layer,
80
+ path: toAssetPath(layer.root, filePath),
81
+ filePath,
82
+ }));
83
+ }
84
+ async function discoverFilePaths(root, directory) {
85
+ let entries;
86
+ try {
87
+ entries = await readdir(directory, { withFileTypes: true });
88
+ }
89
+ catch (error) {
90
+ if (isMissingPath(error) && directory === root) {
91
+ return [];
92
+ }
93
+ throw error;
94
+ }
95
+ const files = [];
96
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
97
+ const entryPath = path.join(directory, entry.name);
98
+ if (entry.isDirectory()) {
99
+ files.push(...(await discoverFilePaths(root, entryPath)));
100
+ }
101
+ else if (entry.isFile()) {
102
+ files.push(entryPath);
103
+ }
104
+ }
105
+ return files;
106
+ }
107
+ async function loadAsset(asset) {
108
+ const raw = await readFile(asset.filePath, "utf8");
109
+ const split = splitFrontmatter(raw, asset.path);
110
+ return {
111
+ path: asset.path,
112
+ content: split.content,
113
+ frontmatter: split.frontmatter,
114
+ source: resolveAssetSource(asset),
115
+ };
116
+ }
117
+ function splitFrontmatter(raw, assetPath) {
118
+ const lines = raw.split(/\r?\n/u);
119
+ if (lines[0] !== FRONTMATTER_DELIMITER) {
120
+ return { frontmatter: null, content: raw };
121
+ }
122
+ const closingIndex = lines.indexOf(FRONTMATTER_DELIMITER, 1);
123
+ if (closingIndex < 0) {
124
+ throw new Error(`Asset frontmatter is missing a closing delimiter: ${assetPath}`);
125
+ }
126
+ const frontmatterText = lines.slice(1, closingIndex).join("\n");
127
+ return {
128
+ frontmatter: frontmatterText.trim().length === 0 ? null : parseYaml(frontmatterText),
129
+ content: lines.slice(closingIndex + 1).join("\n"),
130
+ };
131
+ }
132
+ function resolveAssetSource(asset) {
133
+ if (isSystemEjectedAsset(asset)) {
134
+ return LOADED_ASSET_SOURCE.systemEjected;
135
+ }
136
+ return LOADED_ASSET_SOURCE_BY_LAYER_KIND[asset.layer.kind];
137
+ }
138
+ function isSystemEjectedAsset(asset) {
139
+ return (asset.layer.kind === ASSET_LAYER_KIND.repository &&
140
+ asset.path.split("/").includes(SYSTEM_EJECTED_DIRECTORY));
141
+ }
142
+ function toAssetPath(root, filePath) {
143
+ return normalizeAssetPath(path.relative(root, filePath).split(path.sep).join("/"));
144
+ }
145
+ function normalizeAssetPath(assetPath) {
146
+ const normalized = path.posix.normalize(assetPath);
147
+ if (assetPath.length === 0 ||
148
+ path.isAbsolute(assetPath) ||
149
+ path.win32.isAbsolute(assetPath) ||
150
+ assetPath.includes("\\") ||
151
+ normalized === "." ||
152
+ normalized === ".." ||
153
+ normalized.startsWith("../") ||
154
+ normalized !== assetPath) {
155
+ throw new Error(`Invalid layered asset path: ${assetPath}`);
156
+ }
157
+ return normalized;
158
+ }
159
+ function compareDiagnostics(left, right) {
160
+ return (left.path.localeCompare(right.path) ||
161
+ compareLayerKinds(left.layerKind, right.layerKind));
162
+ }
163
+ function compareLayerKinds(left, right) {
164
+ return left.localeCompare(right);
165
+ }
166
+ function isMissingPath(error) {
167
+ return (error instanceof Error &&
168
+ "code" in error &&
169
+ error.code === "ENOENT");
170
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./fs-layered-asset-source.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./fs-layered-asset-source.js";
@@ -0,0 +1,2 @@
1
+ export declare const SERVICE_DISPLAY_NAME = "AlpacaLoop";
2
+ //# sourceMappingURL=branding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../src/branding.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,eAAe,CAAC"}
@@ -0,0 +1 @@
1
+ export const SERVICE_DISPLAY_NAME = "AlpacaLoop";
@@ -0,0 +1,13 @@
1
+ import { CODEC_DECODE_RESULT_KIND, type CodecDecodeResult } from "./ports.js";
2
+ type DecodedValue<Result> = Result extends {
3
+ readonly kind: typeof CODEC_DECODE_RESULT_KIND.decoded;
4
+ readonly value: infer Value;
5
+ } ? Value : never;
6
+ type DecodedValueTuple<Results extends readonly CodecDecodeResult<unknown>[]> = {
7
+ readonly [Index in keyof Results]: DecodedValue<Results[Index]>;
8
+ };
9
+ export declare function decodedCodecResult<Value>(value: Value): CodecDecodeResult<Value>;
10
+ export declare function invalidCodecResult(issues: readonly [string, ...string[]]): CodecDecodeResult<never>;
11
+ export declare function allCodecDecodeResults<const Results extends readonly CodecDecodeResult<unknown>[]>(results: Results): CodecDecodeResult<DecodedValueTuple<Results>>;
12
+ export {};
13
+ //# sourceMappingURL=decode-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode-result.d.ts","sourceRoot":"","sources":["../src/decode-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE9E,KAAK,YAAY,CAAC,MAAM,IAAI,MAAM,SAAS;IACzC,QAAQ,CAAC,IAAI,EAAE,OAAO,wBAAwB,CAAC,OAAO,CAAC;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC;CAC7B,GACG,KAAK,GACL,KAAK,CAAC;AAEV,KAAK,iBAAiB,CAAC,OAAO,SAAS,SAAS,iBAAiB,CAAC,OAAO,CAAC,EAAE,IAC1E;IACE,QAAQ,EAAE,KAAK,IAAI,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;CAChE,CAAC;AAEJ,wBAAgB,kBAAkB,CAAC,KAAK,EACtC,KAAK,EAAE,KAAK,GACX,iBAAiB,CAAC,KAAK,CAAC,CAE1B;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,GACrC,iBAAiB,CAAC,KAAK,CAAC,CAE1B;AAED,wBAAgB,qBAAqB,CACnC,KAAK,CAAC,OAAO,SAAS,SAAS,iBAAiB,CAAC,OAAO,CAAC,EAAE,EAC3D,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAcjE"}
@@ -0,0 +1,23 @@
1
+ import { CODEC_DECODE_RESULT_KIND } from "./ports.js";
2
+ export function decodedCodecResult(value) {
3
+ return { kind: CODEC_DECODE_RESULT_KIND.decoded, value };
4
+ }
5
+ export function invalidCodecResult(issues) {
6
+ return { kind: CODEC_DECODE_RESULT_KIND.invalid, issues };
7
+ }
8
+ export function allCodecDecodeResults(results) {
9
+ const values = [];
10
+ const issues = [];
11
+ for (const result of results) {
12
+ if (result.kind === CODEC_DECODE_RESULT_KIND.decoded) {
13
+ values.push(result.value);
14
+ }
15
+ else {
16
+ issues.push(...result.issues);
17
+ }
18
+ }
19
+ const [firstIssue, ...remainingIssues] = issues;
20
+ return firstIssue === undefined
21
+ ? decodedCodecResult(values)
22
+ : invalidCodecResult([firstIssue, ...remainingIssues]);
23
+ }
@@ -0,0 +1,6 @@
1
+ export declare const EMPTY_JSON_OBJECT: Readonly<{}>;
2
+ export declare const EMPTY_METADATA: Readonly<{}>;
3
+ export declare const EMPTY_JSON_ARRAY: readonly never[];
4
+ export declare const EMPTY_STRING_LIST: readonly never[];
5
+ export declare const EMPTY_DEFINITION_LIST: readonly never[];
6
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,cAAyC,CAAC;AACxE,eAAO,MAAM,cAAc,cAAuC,CAAC;AACnE,eAAO,MAAM,gBAAgB,kBAAwC,CAAC;AACtE,eAAO,MAAM,iBAAiB,kBAAgD,CAAC;AAC/E,eAAO,MAAM,qBAAqB,kBAEN,CAAC"}
@@ -0,0 +1,5 @@
1
+ export const EMPTY_JSON_OBJECT = Object.freeze({});
2
+ export const EMPTY_METADATA = EMPTY_JSON_OBJECT;
3
+ export const EMPTY_JSON_ARRAY = Object.freeze([]);
4
+ export const EMPTY_STRING_LIST = Object.freeze([]);
5
+ export const EMPTY_DEFINITION_LIST = Object.freeze([]);
@@ -0,0 +1,35 @@
1
+ import type { CodecDecodeResult, Registry, RuntimeCodec } from "./ports.js";
2
+ export interface PayloadCodecDefinition<Key> {
3
+ readonly kind: Key;
4
+ readonly payloadCodec: {
5
+ decode(input: unknown): CodecDecodeResult<unknown>;
6
+ };
7
+ }
8
+ export type PayloadEnvelope<Key, Payload = unknown> = {
9
+ readonly kind: Key;
10
+ readonly payload: Payload;
11
+ };
12
+ export type PayloadOf<Definition> = Definition extends {
13
+ readonly payloadCodec: RuntimeCodec<infer Payload>;
14
+ } ? Payload : unknown;
15
+ export type DecodedPayloadEnvelope<Envelope, Payload> = Omit<Envelope, "payload"> & {
16
+ readonly payload: Payload;
17
+ };
18
+ export declare function routePayloadEnvelope<Key, Definition extends PayloadCodecDefinition<Key>, Envelope extends PayloadEnvelope<Key>, TResult>(input: {
19
+ readonly registry: Registry<Key, Definition>;
20
+ readonly envelope: Envelope;
21
+ readonly onMissingDefinition: (input: {
22
+ readonly envelope: Envelope;
23
+ }) => TResult;
24
+ readonly onInvalidPayload: (input: {
25
+ readonly definition: Definition;
26
+ readonly envelope: Envelope;
27
+ readonly issues: readonly string[];
28
+ }) => TResult;
29
+ readonly onResolved: (input: {
30
+ readonly definition: Definition;
31
+ readonly envelope: DecodedPayloadEnvelope<Envelope, PayloadOf<Definition>>;
32
+ readonly payload: PayloadOf<Definition>;
33
+ }) => TResult;
34
+ }): TResult;
35
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG5E,MAAM,WAAW,sBAAsB,CAAC,GAAG;IACzC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,YAAY,EAAE;QACrB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;KACpD,CAAC;CACH;AAED,MAAM,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,IAAI;IACpD,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,UAAU,IAAI,UAAU,SAAS;IACrD,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,MAAM,OAAO,CAAC,CAAC;CACpD,GACG,OAAO,GACP,OAAO,CAAC;AAEZ,MAAM,MAAM,sBAAsB,CAAC,QAAQ,EAAE,OAAO,IAAI,IAAI,CAC1D,QAAQ,EACR,SAAS,CACV,GAAG;IACF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,GAAG,EACH,UAAU,SAAS,sBAAsB,CAAC,GAAG,CAAC,EAC9C,QAAQ,SAAS,eAAe,CAAC,GAAG,CAAC,EACrC,OAAO,EACP,KAAK,EAAE;IACP,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE;QACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC7B,KAAK,OAAO,CAAC;IACd,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE;QACjC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;KACpC,KAAK,OAAO,CAAC;IACd,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE;QAC3B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3E,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;KACzC,KAAK,OAAO,CAAC;CACf,GAAG,OAAO,CAwBV"}
@@ -0,0 +1,24 @@
1
+ import { CODEC_DECODE_RESULT_KIND } from "./ports.js";
2
+ export function routePayloadEnvelope(input) {
3
+ const definition = input.registry.get(input.envelope.kind);
4
+ if (definition === null) {
5
+ return input.onMissingDefinition({ envelope: input.envelope });
6
+ }
7
+ const decoded = definition.payloadCodec.decode(input.envelope.payload);
8
+ if (decoded.kind === CODEC_DECODE_RESULT_KIND.invalid) {
9
+ return input.onInvalidPayload({
10
+ definition,
11
+ envelope: input.envelope,
12
+ issues: decoded.issues,
13
+ });
14
+ }
15
+ const payload = decoded.value;
16
+ return input.onResolved({
17
+ definition,
18
+ envelope: {
19
+ ...input.envelope,
20
+ payload,
21
+ },
22
+ payload,
23
+ });
24
+ }
@@ -0,0 +1,16 @@
1
+ export type Defaultable<TModel, TDefaultKeys extends keyof TModel> = Omit<TModel, TDefaultKeys> & Partial<Pick<TModel, TDefaultKeys>>;
2
+ export type ModelDefaults<TModel, TDefaultKeys extends keyof TModel> = Required<Pick<TModel, TDefaultKeys>>;
3
+ export interface ModelFactory<TDraft, TModel> {
4
+ create(draft: TDraft): TModel;
5
+ }
6
+ export interface DefaultProvider<TDefaults> {
7
+ readonly defaults: TDefaults;
8
+ }
9
+ export declare function applyModelDefaults<TModel, TDefaultKeys extends keyof TModel>(defaults: ModelDefaults<TModel, TDefaultKeys>, draft: Defaultable<TModel, TDefaultKeys>): TModel;
10
+ export declare class DefaultedModelFactory<TModel, TDefaultKeys extends keyof TModel> implements ModelFactory<Defaultable<TModel, TDefaultKeys>, TModel>, DefaultProvider<ModelDefaults<TModel, TDefaultKeys>> {
11
+ readonly defaults: ModelDefaults<TModel, TDefaultKeys>;
12
+ constructor(defaults: ModelDefaults<TModel, TDefaultKeys>);
13
+ create(draft: Defaultable<TModel, TDefaultKeys>): TModel;
14
+ }
15
+ export declare function createDefaultedModelFactory<TModel, TDefaultKeys extends keyof TModel>(defaults: ModelDefaults<TModel, TDefaultKeys>): ModelFactory<Defaultable<TModel, TDefaultKeys>, TModel>;
16
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,CAAC,MAAM,EAAE,YAAY,SAAS,MAAM,MAAM,IAAI,IAAI,CACvE,MAAM,EACN,YAAY,CACb,GACC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,CAAC,MAAM,EAAE,YAAY,SAAS,MAAM,MAAM,IAAI,QAAQ,CAC7E,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAC3B,CAAC;AAEF,MAAM,WAAW,YAAY,CAAC,MAAM,EAAE,MAAM;IAC1C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe,CAAC,SAAS;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,SAAS,MAAM,MAAM,EAC1E,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7C,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GACvC,MAAM,CAKR;AAED,qBAAa,qBAAqB,CAAC,MAAM,EAAE,YAAY,SAAS,MAAM,MAAM,CAC1E,YACE,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,EACvD,eAAe,CAAC,aAAa,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAE1C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,YAAY,CAAC;gBAA7C,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,YAAY,CAAC;IAElE,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM;CAGzD;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EACN,YAAY,SAAS,MAAM,MAAM,EAEjC,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,YAAY,CAAC,GAC5C,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAEzD"}
@@ -0,0 +1,18 @@
1
+ export function applyModelDefaults(defaults, draft) {
2
+ return {
3
+ ...defaults,
4
+ ...draft,
5
+ };
6
+ }
7
+ export class DefaultedModelFactory {
8
+ defaults;
9
+ constructor(defaults) {
10
+ this.defaults = defaults;
11
+ }
12
+ create(draft) {
13
+ return applyModelDefaults(this.defaults, draft);
14
+ }
15
+ }
16
+ export function createDefaultedModelFactory(defaults) {
17
+ return new DefaultedModelFactory(defaults);
18
+ }
package/dist/ids.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { Brand } from "./types.js";
2
+ export declare const ID_PART_SEPARATOR = ":";
3
+ export declare function joinIdParts(...parts: readonly string[]): string;
4
+ export declare function makeBrandedId<TBrand extends string>(value: string): Brand<string, TBrand>;
5
+ export declare function makeJoinedBrandedId<TBrand extends string>(...parts: readonly string[]): Brand<string, TBrand>;
6
+ type BrandedStringId = string & {
7
+ readonly __brand: string;
8
+ };
9
+ type BrandedNumberId = number & {
10
+ readonly __brand: string;
11
+ };
12
+ export declare function defineStringIdFactory<TId extends BrandedStringId>(): (value: string) => TId;
13
+ export declare function defineNonNegativeIntegerFactory<TId extends BrandedNumberId>(name: string): (value: number) => TId;
14
+ export {};
15
+ //# sourceMappingURL=ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE/D;AAED,wBAAgB,aAAa,CAAC,MAAM,SAAS,MAAM,EACjD,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAMvB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,SAAS,MAAM,EACvD,GAAG,KAAK,EAAE,SAAS,MAAM,EAAE,GAC1B,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAEvB;AAED,KAAK,eAAe,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC7D,KAAK,eAAe,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAgB,qBAAqB,CAAC,GAAG,SAAS,eAAe,KAAK,CACpE,KAAK,EAAE,MAAM,KACV,GAAG,CAEP;AAED,wBAAgB,+BAA+B,CAAC,GAAG,SAAS,eAAe,EACzE,IAAI,EAAE,MAAM,GACX,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAQxB"}
package/dist/ids.js ADDED
@@ -0,0 +1,24 @@
1
+ export const ID_PART_SEPARATOR = ":";
2
+ export function joinIdParts(...parts) {
3
+ return parts.join(ID_PART_SEPARATOR);
4
+ }
5
+ export function makeBrandedId(value) {
6
+ if (value.trim().length === 0) {
7
+ throw new Error("A branded id must be a non-empty string.");
8
+ }
9
+ return value;
10
+ }
11
+ export function makeJoinedBrandedId(...parts) {
12
+ return makeBrandedId(joinIdParts(...parts));
13
+ }
14
+ export function defineStringIdFactory() {
15
+ return (value) => makeBrandedId(value);
16
+ }
17
+ export function defineNonNegativeIntegerFactory(name) {
18
+ return (value) => {
19
+ if (!Number.isInteger(value) || value < 0) {
20
+ throw new Error(`${name} must be a non-negative integer.`);
21
+ }
22
+ return value;
23
+ };
24
+ }
@@ -0,0 +1,14 @@
1
+ export * from "./adapters/index.js";
2
+ export * from "./branding.js";
3
+ export * from "./decode-result.js";
4
+ export * from "./defaults.js";
5
+ export * from "./definition.js";
6
+ export * from "./factory.js";
7
+ export * from "./ids.js";
8
+ export * from "./mutation.js";
9
+ export * from "./pipeline.js";
10
+ export * from "./ports.js";
11
+ export * from "./registry.js";
12
+ export * from "./schema.js";
13
+ export * from "./types.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ export * from "./adapters/index.js";
2
+ export * from "./branding.js";
3
+ export * from "./decode-result.js";
4
+ export * from "./defaults.js";
5
+ export * from "./definition.js";
6
+ export * from "./factory.js";
7
+ export * from "./ids.js";
8
+ export * from "./mutation.js";
9
+ export * from "./pipeline.js";
10
+ export * from "./ports.js";
11
+ export * from "./registry.js";
12
+ export * from "./schema.js";
13
+ export * from "./types.js";
@@ -0,0 +1,11 @@
1
+ import { type Draft } from "immer";
2
+ export type MutableDraft<TValue> = Draft<TValue>;
3
+ type MutableDraftArrayItem<TItem> = TItem extends object ? MutableDraft<TItem> : TItem;
4
+ type MutableDraftArray<TItem> = MutableDraftArrayItem<TItem>[];
5
+ export declare function produceImmutable<TValue>(value: TValue, mutate: (draft: MutableDraft<TValue>) => void): TValue;
6
+ export declare function appendDraftItems<TItem>(draftItems: MutableDraftArray<TItem>, items: readonly TItem[]): void;
7
+ export declare function replaceExistingDraftItemsByKey<TItem, TKey>(draftItems: MutableDraftArray<TItem>, nextItems: readonly TItem[], keyOf: (item: TItem) => TKey): void;
8
+ export declare function removeDraftItemsWhere<TItem>(draftItems: MutableDraftArray<TItem>, predicate: (item: TItem) => boolean): void;
9
+ export declare function removeDraftItemsByKey<TItem, TKey>(draftItems: MutableDraftArray<TItem>, keys: readonly TKey[], keyOf: (item: TItem) => TKey): void;
10
+ export {};
11
+ //# sourceMappingURL=mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation.d.ts","sourceRoot":"","sources":["../src/mutation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,KAAK,EAAW,MAAM,OAAO,CAAC;AAEvD,MAAM,MAAM,YAAY,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;AACjD,KAAK,qBAAqB,CAAC,KAAK,IAAI,KAAK,SAAS,MAAM,GACpD,YAAY,CAAC,KAAK,CAAC,GACnB,KAAK,CAAC;AACV,KAAK,iBAAiB,CAAC,KAAK,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;AAE/D,wBAAgB,gBAAgB,CAAC,MAAM,EACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAC5C,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,EACpC,KAAK,EAAE,SAAS,KAAK,EAAE,GACtB,IAAI,CAEN;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,IAAI,EACxD,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,EACpC,SAAS,EAAE,SAAS,KAAK,EAAE,EAC3B,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAC3B,IAAI,CAUN;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EACzC,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,EACpC,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,GAClC,IAAI,CAMN;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAC/C,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,EACpC,IAAI,EAAE,SAAS,IAAI,EAAE,EACrB,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAC3B,IAAI,CAIN"}
@@ -0,0 +1,32 @@
1
+ import { castDraft, produce } from "immer";
2
+ export function produceImmutable(value, mutate) {
3
+ return produce(value, mutate);
4
+ }
5
+ export function appendDraftItems(draftItems, items) {
6
+ draftItems.push(...toDraftItems(items));
7
+ }
8
+ export function replaceExistingDraftItemsByKey(draftItems, nextItems, keyOf) {
9
+ for (const nextItem of nextItems) {
10
+ const nextKey = keyOf(nextItem);
11
+ const itemIndex = draftItems.findIndex((item) => Object.is(keyOf(item), nextKey));
12
+ if (itemIndex !== -1) {
13
+ draftItems.splice(itemIndex, 1, toDraftItem(nextItem));
14
+ }
15
+ }
16
+ }
17
+ export function removeDraftItemsWhere(draftItems, predicate) {
18
+ for (let index = draftItems.length - 1; index >= 0; index -= 1) {
19
+ if (predicate(draftItems[index])) {
20
+ draftItems.splice(index, 1);
21
+ }
22
+ }
23
+ }
24
+ export function removeDraftItemsByKey(draftItems, keys, keyOf) {
25
+ removeDraftItemsWhere(draftItems, (item) => keys.some((key) => Object.is(keyOf(item), key)));
26
+ }
27
+ function toDraftItem(item) {
28
+ return castDraft(item);
29
+ }
30
+ function toDraftItems(items) {
31
+ return castDraft([...items]);
32
+ }
@@ -0,0 +1,12 @@
1
+ import type { Pipeline } from "./ports.js";
2
+ export interface PipelineStep<State> {
3
+ readonly id: string;
4
+ run(state: State): Promise<State>;
5
+ }
6
+ export declare class SequentialPipeline<State> implements Pipeline<State, State> {
7
+ private readonly steps;
8
+ constructor(steps: readonly PipelineStep<State>[]);
9
+ run(input: State): Promise<State>;
10
+ }
11
+ export declare function createSequentialPipeline<State>(steps: readonly PipelineStep<State>[]): Pipeline<State, State>;
12
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,YAAY,CAAC,KAAK;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;CACnC;AAED,qBAAa,kBAAkB,CAAC,KAAK,CAAE,YAAW,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAC1D,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,SAAS,YAAY,CAAC,KAAK,CAAC,EAAE;IAE5D,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;CASxC;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAC5C,KAAK,EAAE,SAAS,YAAY,CAAC,KAAK,CAAC,EAAE,GACpC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAExB"}
@@ -0,0 +1,16 @@
1
+ export class SequentialPipeline {
2
+ steps;
3
+ constructor(steps) {
4
+ this.steps = steps;
5
+ }
6
+ async run(input) {
7
+ let state = input;
8
+ for (const step of this.steps) {
9
+ state = await step.run(state);
10
+ }
11
+ return state;
12
+ }
13
+ }
14
+ export function createSequentialPipeline(steps) {
15
+ return new SequentialPipeline(steps);
16
+ }
@@ -0,0 +1,91 @@
1
+ import type { ValueOf } from "./types.js";
2
+ export interface Registry<Key, Definition> {
3
+ get(key: Key): Definition | null;
4
+ list(): readonly Definition[];
5
+ }
6
+ export interface Resolver<Input, Output> {
7
+ resolve(input: Input): Output;
8
+ }
9
+ export interface AsyncResolver<Input, Output> {
10
+ resolve(input: Input): Promise<Output>;
11
+ }
12
+ export interface Adapter<Input, Output> {
13
+ execute(input: Input): Promise<Output>;
14
+ }
15
+ export interface Reducer<State, Patch> {
16
+ reduce(state: State, patch: Patch): State;
17
+ }
18
+ export interface Projector<Input, Output> {
19
+ project(input: Input): Output;
20
+ }
21
+ export interface Pipeline<Input, Output> {
22
+ run(input: Input): Promise<Output>;
23
+ }
24
+ export interface Clock {
25
+ /** Epoch milliseconds. */
26
+ now(): number;
27
+ /** Schedule a callback; returns a cancel function. */
28
+ setTimeout(callback: () => void, delayMs: number): () => void;
29
+ }
30
+ export interface HttpClient {
31
+ fetch(url: string, init?: RequestInit): Promise<Response>;
32
+ }
33
+ export interface SecretResolver {
34
+ resolve(id: string): Promise<string | null>;
35
+ }
36
+ export type SecretResolvers = Record<string, SecretResolver>;
37
+ export type SecretRef = {
38
+ readonly resolver: string;
39
+ readonly id: string;
40
+ };
41
+ export declare const ASSET_LAYER_KIND: {
42
+ readonly repository: "repository";
43
+ readonly packagedSystem: "packaged_system";
44
+ };
45
+ export type AssetLayerKind = ValueOf<typeof ASSET_LAYER_KIND>;
46
+ export type AssetLayer = {
47
+ readonly kind: AssetLayerKind;
48
+ readonly root: string;
49
+ };
50
+ export declare const LOADED_ASSET_SOURCE: {
51
+ readonly repository: "repository";
52
+ readonly packagedSystem: "packaged_system";
53
+ readonly systemEjected: "system_ejected";
54
+ };
55
+ export type LoadedAssetSource = ValueOf<typeof LOADED_ASSET_SOURCE>;
56
+ export type LoadedAsset = {
57
+ readonly path: string;
58
+ readonly content: string;
59
+ readonly frontmatter: unknown;
60
+ readonly source: LoadedAssetSource;
61
+ };
62
+ export declare const ASSET_SOURCE_DIAGNOSTIC_KIND: {
63
+ readonly duplicateInLayer: "duplicate_in_layer";
64
+ };
65
+ export type AssetSourceDiagnostic = {
66
+ readonly kind: typeof ASSET_SOURCE_DIAGNOSTIC_KIND.duplicateInLayer;
67
+ readonly path: string;
68
+ readonly layerKind: AssetLayerKind;
69
+ readonly roots: readonly [string, string, ...string[]];
70
+ };
71
+ export interface LayeredAssetSource {
72
+ list(): Promise<readonly LoadedAsset[]>;
73
+ get(path: string): Promise<LoadedAsset | null>;
74
+ diagnostics(): readonly AssetSourceDiagnostic[];
75
+ }
76
+ export declare const CODEC_DECODE_RESULT_KIND: {
77
+ readonly decoded: "decoded";
78
+ readonly invalid: "invalid";
79
+ };
80
+ export type CodecDecodeResult<Value> = {
81
+ readonly kind: typeof CODEC_DECODE_RESULT_KIND.decoded;
82
+ readonly value: Value;
83
+ } | {
84
+ readonly kind: typeof CODEC_DECODE_RESULT_KIND.invalid;
85
+ readonly issues: readonly [string, ...string[]];
86
+ };
87
+ export interface RuntimeCodec<Value> {
88
+ decode(input: unknown): CodecDecodeResult<Value>;
89
+ encode(value: Value): unknown;
90
+ }
91
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../src/ports.ts"],"names":[],"mappings":"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"}
package/dist/ports.js ADDED
@@ -0,0 +1,16 @@
1
+ export const ASSET_LAYER_KIND = {
2
+ repository: "repository",
3
+ packagedSystem: "packaged_system",
4
+ };
5
+ export const LOADED_ASSET_SOURCE = {
6
+ repository: "repository",
7
+ packagedSystem: "packaged_system",
8
+ systemEjected: "system_ejected",
9
+ };
10
+ export const ASSET_SOURCE_DIAGNOSTIC_KIND = {
11
+ duplicateInLayer: "duplicate_in_layer",
12
+ };
13
+ export const CODEC_DECODE_RESULT_KIND = {
14
+ decoded: "decoded",
15
+ invalid: "invalid",
16
+ };
@@ -0,0 +1,30 @@
1
+ import type { AsyncResolver, Registry, Resolver } from "./ports.js";
2
+ export interface Identified<Key extends string> {
3
+ readonly id: Key;
4
+ }
5
+ export type RegistryMatcher<Input, Definition> = (definition: Definition, input: Input) => boolean;
6
+ export type AsyncRegistryMatcher<Input, Definition> = (definition: Definition, input: Input) => Promise<boolean>;
7
+ export declare class MapRegistry<Key extends string, Definition extends Identified<Key>> implements Registry<Key, Definition> {
8
+ private readonly items;
9
+ private readonly itemById;
10
+ constructor(items: readonly Definition[]);
11
+ get(key: Key): Definition | null;
12
+ list(): readonly Definition[];
13
+ }
14
+ export declare class OrderedResolver<Input, Key extends string, Definition extends Identified<Key>> implements Resolver<Input, Definition | null> {
15
+ private readonly registry;
16
+ private readonly matcher;
17
+ constructor(registry: Registry<Key, Definition>, matcher: RegistryMatcher<Input, Definition>);
18
+ resolve(input: Input): Definition | null;
19
+ }
20
+ export declare class AsyncOrderedResolver<Input, Key extends string, Definition extends Identified<Key>> implements AsyncResolver<Input, Definition | null> {
21
+ private readonly registry;
22
+ private readonly matcher;
23
+ constructor(registry: Registry<Key, Definition>, matcher: AsyncRegistryMatcher<Input, Definition>);
24
+ resolve(input: Input): Promise<Definition | null>;
25
+ }
26
+ export declare function createMapRegistry<Key extends string, Definition extends Identified<Key>>(items: readonly Definition[]): Registry<Key, Definition>;
27
+ export declare function createKeyedRegistry<Key, Definition>(items: readonly Definition[], keyOf: (definition: Definition) => Key, formatDuplicateMessage?: (key: Key) => string): Registry<Key, Definition>;
28
+ export declare function createOrderedResolver<Input, Key extends string, Definition extends Identified<Key>>(registry: Registry<Key, Definition>, matcher: RegistryMatcher<Input, Definition>): Resolver<Input, Definition | null>;
29
+ export declare function createAsyncOrderedResolver<Input, Key extends string, Definition extends Identified<Key>>(registry: Registry<Key, Definition>, matcher: AsyncRegistryMatcher<Input, Definition>): AsyncResolver<Input, Definition | null>;
30
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,UAAU,CAAC,GAAG,SAAS,MAAM;IAC5C,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;CAClB;AAED,MAAM,MAAM,eAAe,CAAC,KAAK,EAAE,UAAU,IAAI,CAC/C,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,KACT,OAAO,CAAC;AAEb,MAAM,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,IAAI,CACpD,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,KACT,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,qBAAa,WAAW,CAAC,GAAG,SAAS,MAAM,EAAE,UAAU,SAAS,UAAU,CAAC,GAAG,CAAC,CAC7E,YAAW,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAIxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;gBAE3B,KAAK,EAAE,SAAS,UAAU,EAAE;IAIzD,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,GAAG,IAAI;IAIhC,IAAI,IAAI,SAAS,UAAU,EAAE;CAG9B;AAED,qBAAa,eAAe,CAC1B,KAAK,EACL,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,UAAU,CAAC,GAAG,CAAC,CAClC,YAAW,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAG3C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,EACnC,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC;IAG9D,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI;CASzC;AAED,qBAAa,oBAAoB,CAC/B,KAAK,EACL,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,UAAU,CAAC,GAAG,CAAC,CAClC,YAAW,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAGhD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,EACnC,OAAO,EAAE,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC;IAG7D,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CASxD;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,UAAU,CAAC,GAAG,CAAC,EAClC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAEzD;AAOD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EACjD,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,GAAG,EACtC,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAC5C,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAgB3B;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EACL,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,UAAU,CAAC,GAAG,CAAC,EAElC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,EACnC,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,GAC1C,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC,CAEpC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EACL,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,UAAU,CAAC,GAAG,CAAC,EAElC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,EACnC,OAAO,EAAE,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,GAC/C,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC,CAEzC"}
@@ -0,0 +1,85 @@
1
+ export class MapRegistry {
2
+ items;
3
+ itemById;
4
+ constructor(items) {
5
+ this.items = items;
6
+ this.itemById = buildItemById(items);
7
+ }
8
+ get(key) {
9
+ return this.itemById.get(key) ?? null;
10
+ }
11
+ list() {
12
+ return this.items;
13
+ }
14
+ }
15
+ export class OrderedResolver {
16
+ registry;
17
+ matcher;
18
+ constructor(registry, matcher) {
19
+ this.registry = registry;
20
+ this.matcher = matcher;
21
+ }
22
+ resolve(input) {
23
+ for (const definition of this.registry.list()) {
24
+ if (this.matcher(definition, input)) {
25
+ return definition;
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ }
31
+ export class AsyncOrderedResolver {
32
+ registry;
33
+ matcher;
34
+ constructor(registry, matcher) {
35
+ this.registry = registry;
36
+ this.matcher = matcher;
37
+ }
38
+ async resolve(input) {
39
+ for (const definition of this.registry.list()) {
40
+ if (await this.matcher(definition, input)) {
41
+ return definition;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+ }
47
+ export function createMapRegistry(items) {
48
+ return new MapRegistry(items);
49
+ }
50
+ // For definition rows keyed by something other than `id`, such as strategy
51
+ // and command rows keyed by their `kind`. Registry rows are composition-time
52
+ // definitions, so a duplicate key is a wiring bug: it always throws (matching
53
+ // MapRegistry) instead of silently keeping the last row. Callers pass a
54
+ // formatter when the duplicate message is part of their domain contract.
55
+ export function createKeyedRegistry(items, keyOf, formatDuplicateMessage) {
56
+ const itemByKey = new Map();
57
+ for (const item of items) {
58
+ const key = keyOf(item);
59
+ if (itemByKey.has(key)) {
60
+ throw new Error(formatDuplicateMessage?.(key) ??
61
+ `Duplicate registry item key: ${String(key)}`);
62
+ }
63
+ itemByKey.set(key, item);
64
+ }
65
+ return {
66
+ get: (key) => itemByKey.get(key) ?? null,
67
+ list: () => [...itemByKey.values()],
68
+ };
69
+ }
70
+ export function createOrderedResolver(registry, matcher) {
71
+ return new OrderedResolver(registry, matcher);
72
+ }
73
+ export function createAsyncOrderedResolver(registry, matcher) {
74
+ return new AsyncOrderedResolver(registry, matcher);
75
+ }
76
+ function buildItemById(items) {
77
+ const itemById = new Map();
78
+ for (const item of items) {
79
+ if (itemById.has(item.id)) {
80
+ throw new Error(`Duplicate registry item id: ${item.id}`);
81
+ }
82
+ itemById.set(item.id, item);
83
+ }
84
+ return itemById;
85
+ }
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ import { type RuntimeCodec } from "./ports.js";
3
+ import type { Brand, JsonValue } from "./types.js";
4
+ export declare const stringIdSchema: z.ZodString;
5
+ export declare function brandedStringSchema<TBrand extends string>(): z.ZodType<Brand<string, TBrand>>;
6
+ export declare function readonlyArraySchema<TValue>(schema: z.ZodType<TValue>): z.ZodType<readonly TValue[]>;
7
+ export declare function strictReadonlyObject<TShape extends z.ZodRawShape>(shape: TShape): z.ZodReadonly<z.ZodObject<TShape>>;
8
+ export declare function boundaryReadonlyObject<TShape extends z.ZodRawShape>(shape: TShape): z.ZodReadonly<z.ZodObject<{ -readonly [P in keyof TShape]: TShape[P]; }, z.core.$loose>>;
9
+ export declare function stringValueMapSchema<TValues extends Record<string, string>>(values: TValues): z.ZodEnum<{ [k_1 in TValues[keyof TValues]]: k_1; } extends infer T ? { [k in keyof T]: T[k]; } : never>;
10
+ export declare const jsonPrimitiveSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
11
+ export declare const jsonValueSchema: z.ZodType<JsonValue>;
12
+ export declare const metadataSchema: z.ZodReadonly<z.ZodRecord<z.ZodString, z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>>>;
13
+ export declare function createSchemaRuntimeCodec<Value>(schema: z.ZodType<Value>): RuntimeCodec<Value>;
14
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,KAAK,EAAiB,SAAS,EAAY,MAAM,YAAY,CAAC;AAE5E,eAAO,MAAM,cAAc,aAKvB,CAAC;AAEL,wBAAgB,mBAAmB,CAAC,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,OAAO,CACrE,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CACtB,CAEA;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EACxC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GACxB,CAAC,CAAC,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAE9B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,SAAS,CAAC,CAAC,WAAW,EAC/D,KAAK,EAAE,MAAM,GACZ,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAEpC;AAED,wBAAgB,sBAAsB,CAAC,MAAM,SAAS,CAAC,CAAC,WAAW,EACjE,KAAK,EAAE,MAAM,4FAGd;AAED,wBAAgB,oBAAoB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzE,MAAM,EAAE,OAAO,4GAShB;AAED,eAAO,MAAM,mBAAmB,0EAKK,CAAC;AAEtC,eAAO,MAAM,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAMhD,CAAC;AAEF,eAAO,MAAM,cAAc,sHAEgB,CAAC;AAE5C,wBAAgB,wBAAwB,CAAC,KAAK,EAC5C,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GACvB,YAAY,CAAC,KAAK,CAAC,CAiBrB"}
package/dist/schema.js ADDED
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ import { CODEC_DECODE_RESULT_KIND } from "./ports.js";
3
+ export const stringIdSchema = z
4
+ .string()
5
+ .min(1)
6
+ .refine((value) => value.trim().length > 0, {
7
+ message: "Expected a non-blank string id.",
8
+ });
9
+ export function brandedStringSchema() {
10
+ return stringIdSchema.transform((value) => value);
11
+ }
12
+ export function readonlyArraySchema(schema) {
13
+ return z.array(schema).readonly();
14
+ }
15
+ export function strictReadonlyObject(shape) {
16
+ return z.object(shape).strict().readonly();
17
+ }
18
+ export function boundaryReadonlyObject(shape) {
19
+ return z.object(shape).passthrough().readonly();
20
+ }
21
+ export function stringValueMapSchema(values) {
22
+ const literalValues = Object.values(values);
23
+ if (literalValues.length === 0) {
24
+ throw new Error("Expected at least one string literal value.");
25
+ }
26
+ return z.enum(literalValues);
27
+ }
28
+ export const jsonPrimitiveSchema = z.union([
29
+ z.string(),
30
+ z.number(),
31
+ z.boolean(),
32
+ z.null(),
33
+ ]);
34
+ export const jsonValueSchema = z.lazy(() => z.union([
35
+ jsonPrimitiveSchema,
36
+ z.array(jsonValueSchema).readonly(),
37
+ z.record(z.string(), jsonValueSchema).readonly(),
38
+ ]));
39
+ export const metadataSchema = z
40
+ .record(z.string(), jsonValueSchema)
41
+ .readonly();
42
+ export function createSchemaRuntimeCodec(schema) {
43
+ return {
44
+ decode: (input) => {
45
+ const result = schema.safeParse(input);
46
+ if (result.success) {
47
+ return { kind: CODEC_DECODE_RESULT_KIND.decoded, value: result.data };
48
+ }
49
+ const [firstIssue, ...remainingIssues] = result.error.issues.map((issue) => `${issue.path.join(".") || "$"}: ${issue.message}`);
50
+ return {
51
+ kind: CODEC_DECODE_RESULT_KIND.invalid,
52
+ issues: [firstIssue ?? result.error.message, ...remainingIssues],
53
+ };
54
+ },
55
+ encode: (value) => value,
56
+ };
57
+ }
@@ -0,0 +1,23 @@
1
+ export type Brand<TValue, TBrand extends string> = TValue & {
2
+ readonly __brand: TBrand;
3
+ };
4
+ export type Nullable<TValue> = TValue | null;
5
+ export type ValueOf<TValueMap> = TValueMap[keyof TValueMap];
6
+ export type ReadonlyRecord<TValue> = {
7
+ readonly [key: string]: TValue;
8
+ };
9
+ export type JsonPrimitive = string | number | boolean | null;
10
+ export type JsonValue = JsonPrimitive | readonly JsonValue[] | {
11
+ readonly [key: string]: JsonValue;
12
+ };
13
+ export type JsonArray = readonly JsonValue[];
14
+ export type JsonObject = {
15
+ readonly [key: string]: JsonValue;
16
+ };
17
+ export type Metadata = JsonObject;
18
+ export interface DefinitionBase<Id, Kind extends string, TMetadata> {
19
+ readonly id: Id;
20
+ readonly kind: Kind;
21
+ readonly metadata: TMetadata;
22
+ }
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,SAAS,MAAM,IAAI,MAAM,GAAG;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC;AAE7C,MAAM,MAAM,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;AAE5D,MAAM,MAAM,cAAc,CAAC,MAAM,IAAI;IACnC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAC7D,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,SAAS,SAAS,EAAE,GACpB;IACE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AACN,MAAM,MAAM,SAAS,GAAG,SAAS,SAAS,EAAE,CAAC;AAC7C,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC;AAElC,MAAM,WAAW,cAAc,CAAC,EAAE,EAAE,IAAI,SAAS,MAAM,EAAE,SAAS;IAChE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@alpacakit/core",
3
+ "version": "0.1.0-beta.19",
4
+ "description": "Architecture-neutral kernel primitives: branded ids, ports, registries, pipelines, payload codecs, and immutable mutation helpers.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "types": "./dist/index.d.ts",
14
+ "files": [
15
+ "dist",
16
+ "README*.md",
17
+ "LICENSE"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public",
21
+ "registry": "https://registry.npmjs.org/"
22
+ },
23
+ "dependencies": {
24
+ "immer": "^11.1.8",
25
+ "yaml": "^2.8.4",
26
+ "zod": "^4.3.6"
27
+ },
28
+ "devDependencies": {
29
+ "typescript": "^5.9.3",
30
+ "vitest": "^4.0.18"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc -p tsconfig.build.json",
34
+ "typecheck": "tsc -p tsconfig.json --noEmit",
35
+ "test": "vitest run"
36
+ }
37
+ }