@principles/core 1.74.0 → 1.75.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/runtime-v2/__tests__/architecture-regression.test.js +3 -3
- package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/dist/runtime-v2/activation/index.d.ts +0 -2
- package/dist/runtime-v2/activation/index.d.ts.map +1 -1
- package/dist/runtime-v2/activation/index.js +0 -1
- package/dist/runtime-v2/activation/index.js.map +1 -1
- package/dist/runtime-v2/index.d.ts +4 -4
- package/dist/runtime-v2/index.d.ts.map +1 -1
- package/dist/runtime-v2/index.js +2 -2
- package/dist/runtime-v2/index.js.map +1 -1
- package/dist/runtime-v2/types/event-types.d.ts +3 -24
- package/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/dist/runtime-v2/types/event-types.js +0 -10
- package/dist/runtime-v2/types/event-types.js.map +1 -1
- package/package.json +1 -1
- package/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.d.ts +0 -2
- package/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.d.ts.map +0 -1
- package/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.js +0 -148
- package/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.js.map +0 -1
- package/dist/runtime-v2/activation/sqlite-confirm-first-state-store.d.ts +0 -22
- package/dist/runtime-v2/activation/sqlite-confirm-first-state-store.d.ts.map +0 -1
- package/dist/runtime-v2/activation/sqlite-confirm-first-state-store.js +0 -136
- package/dist/runtime-v2/activation/sqlite-confirm-first-state-store.js.map +0 -1
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import * as os from 'os';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import * as fs from 'fs';
|
|
5
|
-
import { SqliteConfirmFirstStateStore } from '../activation/sqlite-confirm-first-state-store.js';
|
|
6
|
-
import { SqliteConnection } from '../store/sqlite-connection.js';
|
|
7
|
-
describe('SqliteConfirmFirstStateStore', () => {
|
|
8
|
-
let tmpDir = '';
|
|
9
|
-
let connection = null;
|
|
10
|
-
let store = null;
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-cf-test-'));
|
|
13
|
-
connection = new SqliteConnection(tmpDir);
|
|
14
|
-
store = new SqliteConfirmFirstStateStore(connection);
|
|
15
|
-
});
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
connection.close();
|
|
18
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
19
|
-
});
|
|
20
|
-
it('upsertDirective insert: inserts a new directive and getState returns correct record', () => {
|
|
21
|
-
store.upsertDirective('sess-1', true, 'principle-abc');
|
|
22
|
-
const record = store.getState('sess-1');
|
|
23
|
-
expect(record).not.toBeNull();
|
|
24
|
-
if (record) {
|
|
25
|
-
expect(record.sessionId).toBe('sess-1');
|
|
26
|
-
expect(record.directiveActive).toBe(true);
|
|
27
|
-
expect(record.directivePrincipleId).toBe('principle-abc');
|
|
28
|
-
expect(record.directiveSetAt).toBeTruthy();
|
|
29
|
-
expect(record.lastSeenAt).toBeTruthy();
|
|
30
|
-
expect(record.approvalActive).toBe(false);
|
|
31
|
-
expect(record.approvalSetAt).toBeNull();
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
it('upsertDirective update: updates directive while preserving approval fields', () => {
|
|
35
|
-
store.upsertDirective('sess-2', true, 'p-old');
|
|
36
|
-
store.upsertApproval('sess-2');
|
|
37
|
-
store.upsertDirective('sess-2', false, 'p-new');
|
|
38
|
-
const record = store.getState('sess-2');
|
|
39
|
-
expect(record).not.toBeNull();
|
|
40
|
-
if (record) {
|
|
41
|
-
expect(record.directiveActive).toBe(false);
|
|
42
|
-
expect(record.directivePrincipleId).toBe('p-new');
|
|
43
|
-
expect(record.approvalActive).toBe(true);
|
|
44
|
-
expect(record.approvalSetAt).not.toBeNull();
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
it('upsertApproval on existing row: sets approval fields on a row with prior directive', () => {
|
|
48
|
-
store.upsertDirective('sess-3', true, 'p-1');
|
|
49
|
-
store.upsertApproval('sess-3');
|
|
50
|
-
const record = store.getState('sess-3');
|
|
51
|
-
expect(record).not.toBeNull();
|
|
52
|
-
if (record) {
|
|
53
|
-
expect(record.directiveActive).toBe(true);
|
|
54
|
-
expect(record.directivePrincipleId).toBe('p-1');
|
|
55
|
-
expect(record.approvalActive).toBe(true);
|
|
56
|
-
expect(record.approvalSetAt).not.toBeNull();
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
it('upsertApproval on non-existent row: creates row with directive_active=0', () => {
|
|
60
|
-
store.upsertApproval('sess-4');
|
|
61
|
-
const db = connection.getDb();
|
|
62
|
-
const row = db.prepare('SELECT session_id, directive_active, approval_active FROM confirm_first_state WHERE session_id = ?').get('sess-4');
|
|
63
|
-
expect(row).toBeDefined();
|
|
64
|
-
if (row) {
|
|
65
|
-
expect(row.session_id).toBe('sess-4');
|
|
66
|
-
expect(row.directive_active).toBe(0);
|
|
67
|
-
expect(row.approval_active).toBe(1);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
it('getState returns null for missing session', () => {
|
|
71
|
-
const result = store.getState('nonexistent');
|
|
72
|
-
expect(result).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
it('deleteState: removes a specific session record', () => {
|
|
75
|
-
store.upsertDirective('sess-5', true, 'p-del');
|
|
76
|
-
store.deleteState('sess-5');
|
|
77
|
-
expect(store.getState('sess-5')).toBeNull();
|
|
78
|
-
});
|
|
79
|
-
it('deleteAllState: removes all session records', () => {
|
|
80
|
-
store.upsertDirective('sess-a', true, 'p-a');
|
|
81
|
-
store.upsertDirective('sess-b', true, 'p-b');
|
|
82
|
-
store.upsertDirective('sess-c', true, 'p-c');
|
|
83
|
-
store.deleteAllState();
|
|
84
|
-
expect(store.getAllState()).toEqual([]);
|
|
85
|
-
});
|
|
86
|
-
it('pruneStaleRows with old rows: deletes rows older than 30 days', () => {
|
|
87
|
-
const db = connection.getDb();
|
|
88
|
-
const oldDate = '2020-01-01T00:00:00Z';
|
|
89
|
-
db.prepare(`INSERT INTO confirm_first_state (session_id, directive_active, directive_set_at, last_seen_at) VALUES (?, 1, ?, ?)`).run('old-sess-1', oldDate, oldDate);
|
|
90
|
-
db.prepare(`INSERT INTO confirm_first_state (session_id, directive_active, directive_set_at, last_seen_at) VALUES (?, 1, ?, ?)`).run('old-sess-2', oldDate, oldDate);
|
|
91
|
-
store.upsertDirective('fresh-sess', true, 'p-fresh');
|
|
92
|
-
const pruned = store.pruneStaleRows();
|
|
93
|
-
expect(pruned).toBe(2);
|
|
94
|
-
expect(store.getState('old-sess-1')).toBeNull();
|
|
95
|
-
expect(store.getState('old-sess-2')).toBeNull();
|
|
96
|
-
expect(store.getState('fresh-sess')).not.toBeNull();
|
|
97
|
-
});
|
|
98
|
-
it('pruneStaleRows with > 500 rows: evicts oldest rows keeping only 500', () => {
|
|
99
|
-
const db = connection.getDb();
|
|
100
|
-
for (let i = 0; i < 502; i++) {
|
|
101
|
-
const id = `sess-${String(i).padStart(4, '0')}`;
|
|
102
|
-
db.prepare(`INSERT INTO confirm_first_state (session_id, directive_active, directive_set_at, last_seen_at) VALUES (?, 1, ?, ?)`).run(id, '2026-05-30T00:00:00Z', '2026-05-30T00:00:00Z');
|
|
103
|
-
}
|
|
104
|
-
const pruned = store.pruneStaleRows();
|
|
105
|
-
expect(pruned).toBe(2);
|
|
106
|
-
const all = store.getAllState();
|
|
107
|
-
expect(all).toHaveLength(500);
|
|
108
|
-
expect(store.getState('sess-0000')).toBeNull();
|
|
109
|
-
expect(store.getState('sess-0001')).toBeNull();
|
|
110
|
-
expect(store.getState('sess-0002')).not.toBeNull();
|
|
111
|
-
});
|
|
112
|
-
it('concurrent upsertApproval: calling upsertApproval twice for same session yields single coherent row', () => {
|
|
113
|
-
store.upsertApproval('sess-dup');
|
|
114
|
-
store.upsertApproval('sess-dup');
|
|
115
|
-
const db = connection.getDb();
|
|
116
|
-
const rows = db.prepare('SELECT session_id, approval_active, approval_set_at FROM confirm_first_state WHERE session_id = ?').all('sess-dup');
|
|
117
|
-
expect(rows).toHaveLength(1);
|
|
118
|
-
const [firstRow] = rows;
|
|
119
|
-
if (firstRow) {
|
|
120
|
-
expect(firstRow.session_id).toBe('sess-dup');
|
|
121
|
-
expect(firstRow.approval_active).toBe(1);
|
|
122
|
-
expect(firstRow.approval_set_at).toBeTruthy();
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
it('fresh workspace: getState returns null without error on a new connection', () => {
|
|
126
|
-
const freshTmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-cf-fresh-'));
|
|
127
|
-
try {
|
|
128
|
-
const freshConn = new SqliteConnection(freshTmpDir);
|
|
129
|
-
const freshStore = new SqliteConfirmFirstStateStore(freshConn);
|
|
130
|
-
const result = freshStore.getState('no-such-session');
|
|
131
|
-
expect(result).toBeNull();
|
|
132
|
-
freshConn.close();
|
|
133
|
-
}
|
|
134
|
-
finally {
|
|
135
|
-
fs.rmSync(freshTmpDir, { recursive: true, force: true });
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
it('getAllState: returns all inserted records', () => {
|
|
139
|
-
store.upsertDirective('sess-g1', true, 'p-g1');
|
|
140
|
-
store.upsertDirective('sess-g2', false, 'p-g2');
|
|
141
|
-
store.upsertDirective('sess-g3', true, 'p-g3');
|
|
142
|
-
const all = store.getAllState();
|
|
143
|
-
expect(all).toHaveLength(3);
|
|
144
|
-
const ids = all.map(r => r.sessionId).sort();
|
|
145
|
-
expect(ids).toEqual(['sess-g1', 'sess-g2', 'sess-g3']);
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
//# sourceMappingURL=sqlite-confirm-first-state-store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-confirm-first-state-store.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { SqliteConnection } from '../store/sqlite-connection.js';
|
|
2
|
-
export interface ConfirmFirstStateRecord {
|
|
3
|
-
sessionId: string;
|
|
4
|
-
directiveActive: boolean;
|
|
5
|
-
directivePrincipleId: string | null;
|
|
6
|
-
directiveSetAt: string;
|
|
7
|
-
approvalActive: boolean;
|
|
8
|
-
approvalSetAt: string | null;
|
|
9
|
-
lastSeenAt: string;
|
|
10
|
-
}
|
|
11
|
-
export declare class SqliteConfirmFirstStateStore {
|
|
12
|
-
private readonly connection;
|
|
13
|
-
constructor(connection: SqliteConnection);
|
|
14
|
-
upsertDirective(sessionId: string, active: boolean, principleId?: string | null): void;
|
|
15
|
-
upsertApproval(sessionId: string): void;
|
|
16
|
-
getState(sessionId: string): ConfirmFirstStateRecord | null;
|
|
17
|
-
deleteState(sessionId: string): void;
|
|
18
|
-
deleteAllState(): void;
|
|
19
|
-
pruneStaleRows(): number;
|
|
20
|
-
getAllState(): ConfirmFirstStateRecord[];
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=sqlite-confirm-first-state-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-confirm-first-state-store.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/activation/sqlite-confirm-first-state-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAwCD,qBAAa,4BAA4B;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,gBAAgB;IAEzD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IActF,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAavC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI;IAgB3D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpC,cAAc,IAAI,IAAI;IAKtB,cAAc,IAAI,MAAM;IA2BxB,WAAW,IAAI,uBAAuB,EAAE;CAsBzC"}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
const MAX_SESSION_ENTRIES = 500;
|
|
2
|
-
const STALE_ROW_DAYS = 30;
|
|
3
|
-
function isRecord(value) {
|
|
4
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
5
|
-
}
|
|
6
|
-
function readStringField(row, key) {
|
|
7
|
-
if (!Object.hasOwn(row, key))
|
|
8
|
-
return null;
|
|
9
|
-
const val = row[key];
|
|
10
|
-
return typeof val === 'string' && val.length > 0 ? val : null;
|
|
11
|
-
}
|
|
12
|
-
function mapRowToRecord(row) {
|
|
13
|
-
if (!isRecord(row))
|
|
14
|
-
return null;
|
|
15
|
-
const sessionId = readStringField(row, 'session_id');
|
|
16
|
-
const directiveSetAt = readStringField(row, 'directive_set_at');
|
|
17
|
-
const lastSeenAt = readStringField(row, 'last_seen_at');
|
|
18
|
-
if (!sessionId || !directiveSetAt || !lastSeenAt)
|
|
19
|
-
return null;
|
|
20
|
-
const directiveActive = row.directive_active === 1;
|
|
21
|
-
const directivePrincipleId = readStringField(row, 'directive_principle_id');
|
|
22
|
-
const approvalActive = row.approval_active === 1;
|
|
23
|
-
const approvalSetAt = readStringField(row, 'approval_set_at');
|
|
24
|
-
return {
|
|
25
|
-
sessionId,
|
|
26
|
-
directiveActive,
|
|
27
|
-
directivePrincipleId,
|
|
28
|
-
directiveSetAt,
|
|
29
|
-
approvalActive,
|
|
30
|
-
approvalSetAt,
|
|
31
|
-
lastSeenAt,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
export class SqliteConfirmFirstStateStore {
|
|
35
|
-
connection;
|
|
36
|
-
constructor(connection) {
|
|
37
|
-
this.connection = connection;
|
|
38
|
-
}
|
|
39
|
-
upsertDirective(sessionId, active, principleId) {
|
|
40
|
-
const db = this.connection.getDb();
|
|
41
|
-
const now = new Date().toISOString();
|
|
42
|
-
db.prepare(`
|
|
43
|
-
INSERT INTO confirm_first_state (session_id, directive_active, directive_principle_id, directive_set_at, last_seen_at)
|
|
44
|
-
VALUES (?, ?, ?, ?, ?)
|
|
45
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
46
|
-
directive_active=excluded.directive_active,
|
|
47
|
-
directive_principle_id=excluded.directive_principle_id,
|
|
48
|
-
directive_set_at=excluded.directive_set_at,
|
|
49
|
-
last_seen_at=excluded.last_seen_at
|
|
50
|
-
`).run(sessionId, active ? 1 : 0, principleId ?? null, now, now);
|
|
51
|
-
}
|
|
52
|
-
upsertApproval(sessionId) {
|
|
53
|
-
const db = this.connection.getDb();
|
|
54
|
-
const now = new Date().toISOString();
|
|
55
|
-
db.prepare(`
|
|
56
|
-
INSERT INTO confirm_first_state (session_id, approval_active, approval_set_at, last_seen_at, directive_active, directive_set_at)
|
|
57
|
-
VALUES (?, 1, ?, ?, 0, '')
|
|
58
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
59
|
-
approval_active=1,
|
|
60
|
-
approval_set_at=excluded.approval_set_at,
|
|
61
|
-
last_seen_at=excluded.last_seen_at
|
|
62
|
-
`).run(sessionId, now, now);
|
|
63
|
-
}
|
|
64
|
-
getState(sessionId) {
|
|
65
|
-
try {
|
|
66
|
-
const db = this.connection.getDb();
|
|
67
|
-
const row = db.prepare(`
|
|
68
|
-
SELECT session_id, directive_active, directive_principle_id, directive_set_at,
|
|
69
|
-
approval_active, approval_set_at, last_seen_at
|
|
70
|
-
FROM confirm_first_state
|
|
71
|
-
WHERE session_id = ?
|
|
72
|
-
`).get(sessionId);
|
|
73
|
-
return mapRowToRecord(row);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
if (err instanceof Error && err.message.includes('no such table'))
|
|
77
|
-
return null;
|
|
78
|
-
throw err;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
deleteState(sessionId) {
|
|
82
|
-
const db = this.connection.getDb();
|
|
83
|
-
db.prepare('DELETE FROM confirm_first_state WHERE session_id = ?').run(sessionId);
|
|
84
|
-
}
|
|
85
|
-
deleteAllState() {
|
|
86
|
-
const db = this.connection.getDb();
|
|
87
|
-
db.prepare('DELETE FROM confirm_first_state').run();
|
|
88
|
-
}
|
|
89
|
-
pruneStaleRows() {
|
|
90
|
-
const db = this.connection.getDb();
|
|
91
|
-
const staleResult = db.prepare(`DELETE FROM confirm_first_state WHERE datetime(last_seen_at) < datetime('now', '-${STALE_ROW_DAYS} days')`).run();
|
|
92
|
-
let pruned = staleResult.changes;
|
|
93
|
-
const countRow = db.prepare('SELECT COUNT(*) as cnt FROM confirm_first_state').get();
|
|
94
|
-
if (isRecord(countRow) && Object.hasOwn(countRow, 'cnt')) {
|
|
95
|
-
const total = Number(countRow.cnt);
|
|
96
|
-
if (total > MAX_SESSION_ENTRIES) {
|
|
97
|
-
const excess = total - MAX_SESSION_ENTRIES;
|
|
98
|
-
const excessResult = db.prepare(`
|
|
99
|
-
DELETE FROM confirm_first_state
|
|
100
|
-
WHERE session_id IN (
|
|
101
|
-
SELECT session_id FROM confirm_first_state
|
|
102
|
-
ORDER BY last_seen_at ASC
|
|
103
|
-
LIMIT ?
|
|
104
|
-
)
|
|
105
|
-
`).run(excess);
|
|
106
|
-
pruned += excessResult.changes;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return pruned;
|
|
110
|
-
}
|
|
111
|
-
getAllState() {
|
|
112
|
-
try {
|
|
113
|
-
const db = this.connection.getDb();
|
|
114
|
-
const rows = db.prepare(`
|
|
115
|
-
SELECT session_id, directive_active, directive_principle_id, directive_set_at,
|
|
116
|
-
approval_active, approval_set_at, last_seen_at
|
|
117
|
-
FROM confirm_first_state
|
|
118
|
-
`).all();
|
|
119
|
-
if (!Array.isArray(rows))
|
|
120
|
-
return [];
|
|
121
|
-
const result = [];
|
|
122
|
-
for (const row of rows) {
|
|
123
|
-
const record = mapRowToRecord(row);
|
|
124
|
-
if (record)
|
|
125
|
-
result.push(record);
|
|
126
|
-
}
|
|
127
|
-
return result;
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
if (err instanceof Error && err.message.includes('no such table'))
|
|
131
|
-
return [];
|
|
132
|
-
throw err;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
//# sourceMappingURL=sqlite-confirm-first-state-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-confirm-first-state-store.js","sourceRoot":"","sources":["../../../src/runtime-v2/activation/sqlite-confirm-first-state-store.ts"],"names":[],"mappings":"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"}
|