@voyantjs/action-ledger 0.52.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.
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ import type { ActionLedgerEntry } from "./schema.js";
3
+ export type ActionLedgerTimelineCursor = {
4
+ occurredAt: string;
5
+ id: string;
6
+ };
7
+ export type ActionLedgerSerializedEntry = Omit<ActionLedgerEntry, "occurredAt" | "createdAt"> & {
8
+ occurredAt: string;
9
+ createdAt: string;
10
+ };
11
+ export type ActionLedgerTargetTimelineEntry = ActionLedgerSerializedEntry & {
12
+ mutationSummary: string | null;
13
+ };
14
+ export interface ActionLedgerTargetTimelinePage {
15
+ data: ActionLedgerTargetTimelineEntry[];
16
+ pageInfo: {
17
+ nextCursor: ActionLedgerTimelineCursor | null;
18
+ };
19
+ }
20
+ export declare const actionLedgerTargetTimelineQuerySchema: z.ZodPipe<z.ZodObject<{
21
+ cursorOccurredAt: z.ZodOptional<z.ZodString>;
22
+ cursorId: z.ZodOptional<z.ZodString>;
23
+ limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
24
+ }, z.core.$strip>, z.ZodTransform<{
25
+ cursor: {
26
+ occurredAt: string;
27
+ id: string;
28
+ } | undefined;
29
+ limit?: number | undefined;
30
+ }, {
31
+ cursorOccurredAt?: string | undefined;
32
+ cursorId?: string | undefined;
33
+ limit?: number | undefined;
34
+ }>>;
35
+ export type ActionLedgerTargetTimelineQuery = z.infer<typeof actionLedgerTargetTimelineQuerySchema>;
36
+ export declare function serializeActionLedgerDate(value: Date | string): string;
37
+ export declare function serializeActionLedgerEntry(entry: ActionLedgerEntry): ActionLedgerSerializedEntry;
38
+ export declare function toActionLedgerTimelineCursor(entry: Pick<ActionLedgerEntry, "occurredAt" | "id">): ActionLedgerTimelineCursor;
39
+ export declare function sortActionLedgerTimelineEntries(entries: ActionLedgerEntry[]): ActionLedgerEntry[];
40
+ export declare function buildActionLedgerTargetTimelinePage({ entries, limit, mutationSummariesByActionId, }: {
41
+ entries: ActionLedgerEntry[];
42
+ limit: number;
43
+ mutationSummariesByActionId?: ReadonlyMap<string, string | null>;
44
+ }): ActionLedgerTargetTimelinePage;
45
+ export declare const __test__: {
46
+ actionLedgerTargetTimelineQuerySchema: z.ZodPipe<z.ZodObject<{
47
+ cursorOccurredAt: z.ZodOptional<z.ZodString>;
48
+ cursorId: z.ZodOptional<z.ZodString>;
49
+ limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
50
+ }, z.core.$strip>, z.ZodTransform<{
51
+ cursor: {
52
+ occurredAt: string;
53
+ id: string;
54
+ } | undefined;
55
+ limit?: number | undefined;
56
+ }, {
57
+ cursorOccurredAt?: string | undefined;
58
+ cursorId?: string | undefined;
59
+ limit?: number | undefined;
60
+ }>>;
61
+ buildActionLedgerTargetTimelinePage: typeof buildActionLedgerTargetTimelinePage;
62
+ serializeActionLedgerDate: typeof serializeActionLedgerDate;
63
+ serializeActionLedgerEntry: typeof serializeActionLedgerEntry;
64
+ sortActionLedgerTimelineEntries: typeof sortActionLedgerTimelineEntries;
65
+ toActionLedgerTimelineCursor: typeof toActionLedgerTimelineCursor;
66
+ };
67
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;CACX,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG;IAC9F,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,+BAA+B,GAAG,2BAA2B,GAAG;IAC1E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,+BAA+B,EAAE,CAAA;IACvC,QAAQ,EAAE;QACR,UAAU,EAAE,0BAA0B,GAAG,IAAI,CAAA;KAC9C,CAAA;CACF;AAED,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;GAwB7C,CAAA;AAEL,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAA;AAEnG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAMtE;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,GAAG,2BAA2B,CAMhG;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,IAAI,CAAC,GAClD,0BAA0B,CAK5B;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAMjG;AAED,wBAAgB,mCAAmC,CAAC,EAClD,OAAO,EACP,KAAK,EACL,2BAAuC,GACxC,EAAE;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAA;CACjE,GAAG,8BAA8B,CAoBjC;AAED,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;CAOpB,CAAA"}
@@ -0,0 +1,79 @@
1
+ import { z } from "zod";
2
+ export const actionLedgerTargetTimelineQuerySchema = z
3
+ .object({
4
+ cursorOccurredAt: z.string().datetime().optional(),
5
+ cursorId: z.string().trim().min(1).optional(),
6
+ limit: z.coerce.number().int().min(1).max(199).optional(),
7
+ })
8
+ .superRefine((value, ctx) => {
9
+ if (Boolean(value.cursorOccurredAt) === Boolean(value.cursorId))
10
+ return;
11
+ ctx.addIssue({
12
+ code: z.ZodIssueCode.custom,
13
+ path: value.cursorOccurredAt ? ["cursorId"] : ["cursorOccurredAt"],
14
+ message: "cursorOccurredAt and cursorId must be provided together",
15
+ });
16
+ })
17
+ .transform(({ cursorOccurredAt, cursorId, ...query }) => ({
18
+ ...query,
19
+ cursor: cursorOccurredAt && cursorId
20
+ ? {
21
+ occurredAt: cursorOccurredAt,
22
+ id: cursorId,
23
+ }
24
+ : undefined,
25
+ }));
26
+ export function serializeActionLedgerDate(value) {
27
+ const date = value instanceof Date ? value : new Date(value);
28
+ if (Number.isNaN(date.getTime())) {
29
+ throw new Error("Action ledger timeline timestamp must be a valid date");
30
+ }
31
+ return date.toISOString();
32
+ }
33
+ export function serializeActionLedgerEntry(entry) {
34
+ return {
35
+ ...entry,
36
+ occurredAt: serializeActionLedgerDate(entry.occurredAt),
37
+ createdAt: serializeActionLedgerDate(entry.createdAt),
38
+ };
39
+ }
40
+ export function toActionLedgerTimelineCursor(entry) {
41
+ return {
42
+ occurredAt: serializeActionLedgerDate(entry.occurredAt),
43
+ id: entry.id,
44
+ };
45
+ }
46
+ export function sortActionLedgerTimelineEntries(entries) {
47
+ return [...entries].sort((a, b) => {
48
+ const occurredAtDelta = new Date(b.occurredAt).getTime() - new Date(a.occurredAt).getTime();
49
+ if (occurredAtDelta !== 0)
50
+ return occurredAtDelta;
51
+ return b.id.localeCompare(a.id);
52
+ });
53
+ }
54
+ export function buildActionLedgerTargetTimelinePage({ entries, limit, mutationSummariesByActionId = new Map(), }) {
55
+ const entriesById = new Map();
56
+ for (const entry of entries) {
57
+ entriesById.set(entry.id, entry);
58
+ }
59
+ const sortedEntries = sortActionLedgerTimelineEntries([...entriesById.values()]);
60
+ const visibleEntries = sortedEntries.slice(0, limit);
61
+ const lastEntry = visibleEntries.at(-1);
62
+ return {
63
+ data: visibleEntries.map((entry) => ({
64
+ ...serializeActionLedgerEntry(entry),
65
+ mutationSummary: mutationSummariesByActionId.get(entry.id) ?? null,
66
+ })),
67
+ pageInfo: {
68
+ nextCursor: sortedEntries.length > limit && lastEntry ? toActionLedgerTimelineCursor(lastEntry) : null,
69
+ },
70
+ };
71
+ }
72
+ export const __test__ = {
73
+ actionLedgerTargetTimelineQuerySchema,
74
+ buildActionLedgerTargetTimelinePage,
75
+ serializeActionLedgerDate,
76
+ serializeActionLedgerEntry,
77
+ sortActionLedgerTimelineEntries,
78
+ toActionLedgerTimelineCursor,
79
+ };
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@voyantjs/action-ledger",
3
+ "version": "0.52.2",
4
+ "description": "Action ledger schema, append-only write helpers, and idempotency primitives for Voyant control surfaces.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./canary": "./src/canary.ts",
10
+ "./capability": "./src/capability.ts",
11
+ "./schema": "./src/schema.ts",
12
+ "./service": "./src/service.ts",
13
+ "./fingerprint": "./src/fingerprint.ts",
14
+ "./timeline": "./src/timeline.ts",
15
+ "./request-context": "./src/request-context.ts",
16
+ "./routes": "./src/routes.ts"
17
+ },
18
+ "scripts": {
19
+ "typecheck": "tsc --noEmit",
20
+ "lint": "biome check src/ tests/",
21
+ "test": "vitest run --passWithNoTests",
22
+ "build": "tsc -p tsconfig.json",
23
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
24
+ "prepack": "pnpm run build"
25
+ },
26
+ "dependencies": {
27
+ "@voyantjs/core": "workspace:*",
28
+ "@voyantjs/db": "workspace:*",
29
+ "@voyantjs/hono": "workspace:*",
30
+ "drizzle-orm": "^0.45.2",
31
+ "hono": "^4.12.10",
32
+ "zod": "^4.3.6"
33
+ },
34
+ "devDependencies": {
35
+ "@voyantjs/voyant-typescript-config": "workspace:*",
36
+ "typescript": "^6.0.2",
37
+ "vitest": "^4.1.2"
38
+ },
39
+ "files": [
40
+ "dist"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "main": "./dist/index.js",
45
+ "types": "./dist/index.d.ts",
46
+ "exports": {
47
+ ".": {
48
+ "types": "./dist/index.d.ts",
49
+ "import": "./dist/index.js",
50
+ "default": "./dist/index.js"
51
+ },
52
+ "./canary": {
53
+ "types": "./dist/canary.d.ts",
54
+ "import": "./dist/canary.js",
55
+ "default": "./dist/canary.js"
56
+ },
57
+ "./capability": {
58
+ "types": "./dist/capability.d.ts",
59
+ "import": "./dist/capability.js",
60
+ "default": "./dist/capability.js"
61
+ },
62
+ "./schema": {
63
+ "types": "./dist/schema.d.ts",
64
+ "import": "./dist/schema.js",
65
+ "default": "./dist/schema.js"
66
+ },
67
+ "./service": {
68
+ "types": "./dist/service.d.ts",
69
+ "import": "./dist/service.js",
70
+ "default": "./dist/service.js"
71
+ },
72
+ "./fingerprint": {
73
+ "types": "./dist/fingerprint.d.ts",
74
+ "import": "./dist/fingerprint.js",
75
+ "default": "./dist/fingerprint.js"
76
+ },
77
+ "./timeline": {
78
+ "types": "./dist/timeline.d.ts",
79
+ "import": "./dist/timeline.js",
80
+ "default": "./dist/timeline.js"
81
+ },
82
+ "./request-context": {
83
+ "types": "./dist/request-context.d.ts",
84
+ "import": "./dist/request-context.js",
85
+ "default": "./dist/request-context.js"
86
+ },
87
+ "./routes": {
88
+ "types": "./dist/routes.d.ts",
89
+ "import": "./dist/routes.js",
90
+ "default": "./dist/routes.js"
91
+ }
92
+ }
93
+ },
94
+ "repository": {
95
+ "type": "git",
96
+ "url": "https://github.com/voyantjs/voyant.git",
97
+ "directory": "packages/action-ledger"
98
+ },
99
+ "voyant": {
100
+ "schema": "./schema",
101
+ "requiresSchemas": [
102
+ "@voyantjs/db"
103
+ ]
104
+ }
105
+ }