@fadhilp/stateql 0.11.0 → 0.11.1
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 +34 -10
- package/dist/src/index.d.ts +1 -1
- package/dist/src/stateql.d.ts +3 -1
- package/dist/src/stateql.js +22 -1
- package/dist/src/store.d.ts +1 -0
- package/dist/src/store.js +50 -0
- package/dist/src/types.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -479,16 +479,40 @@ context as `options.executionContext` for all commands in that batch.
|
|
|
479
479
|
|
|
480
480
|
### Actor workspaces
|
|
481
481
|
|
|
482
|
-
`StateQL.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
482
|
+
`StateQL.forWorkspace(...)` is a trusted-host primitive that atomically creates
|
|
483
|
+
or reopens a durable workspace, attaches the requested actor, and returns a
|
|
484
|
+
client bound to that actor:
|
|
485
|
+
|
|
486
|
+
```ts
|
|
487
|
+
const stateql = StateQL.forWorkspace({
|
|
488
|
+
home: "./.stql",
|
|
489
|
+
workspace: "pylon-global",
|
|
490
|
+
actor: "pylon-session:abc123",
|
|
491
|
+
credentialResolver,
|
|
492
|
+
signal,
|
|
493
|
+
});
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Repeated opens of the same actor and workspace are idempotent. An actor already
|
|
497
|
+
attached elsewhere fails with a `StateQLError` whose code is
|
|
498
|
+
`PERMISSION_DENIED`; StateQL never moves or merges it. All actor options,
|
|
499
|
+
including limits, credential resolution, cancellation, `home`, and `now`, are
|
|
500
|
+
preserved. The workspace name also reserves a same-named actor identity for
|
|
501
|
+
legacy compatibility, so workspace and actor identifiers must be globally
|
|
502
|
+
collision-free. The returned client is still bound only to `actor`, preserving
|
|
503
|
+
plan, transaction, operation, and history ownership.
|
|
504
|
+
|
|
505
|
+
`StateQL.forActor(...)` retains its existing behavior: it resolves the actor's
|
|
506
|
+
attached session directly from StateQL storage and creates a legacy-compatible
|
|
507
|
+
session named after the actor on first use. Use `new StateQL({ session, actor })`
|
|
508
|
+
when the session and membership are already known.
|
|
509
|
+
|
|
510
|
+
Membership management and `forWorkspace` are library-only host capabilities,
|
|
511
|
+
not batch or CLI commands. Existing member-authorized management remains
|
|
512
|
+
available through `linkActor(session, actorId)`, `unlinkActor(session, actorId)`,
|
|
513
|
+
`listActors(session)`, and `resolveActor(actorId)`. Integrations should ask for
|
|
514
|
+
user confirmation before changing membership or the shared connection; a host
|
|
515
|
+
calling `forWorkspace` is responsible for authorizing that workspace access.
|
|
492
516
|
|
|
493
517
|
### Harness credential resolution
|
|
494
518
|
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { StateQL } from "./stateql.js";
|
|
|
2
2
|
export { CredentialResolutionError, StateQLError, exitCodeFor, } from "./errors.js";
|
|
3
3
|
export type { CredentialResolutionFailure } from "./errors.js";
|
|
4
4
|
export type { TableChange, TableIdentity, TableUpdate } from "./table-editor.js";
|
|
5
|
-
export type { ActorData, ActorLinkData, ActorResolutionData, ActorsData, ActorUnlinkData, AliasData, ApplyData, BatchCommand, BatchCommandName, BatchOptions, CatalogObject, CatalogObjectKind, DescribeObjectData, ListObjectsData, ListObjectsFilter, CapabilitiesData, CommandExecutionContext, CommandOrigin, CloseSessionData, Column, ColumnsData, CommitTransactionData, ConnectOptions, ConnectionData, CountData, CredentialAccess, CredentialOperation, CredentialRequest, CredentialSource, CredentialResolver, DisconnectData, DoctorData, Driver, ExecData, ExecOptions, ExecutionOptions, ExportData, Failure, FilterOptions, HistoryData, HistoryEntry, HistoryCategory, HistoryOptions, MongoAggregateOptions, MongoDocument, MongoFindOptions, MongoMutationOptions, MongoExecOptions, MongoPlanOptions, MongoQueryOptions, MongoReadCommand, MongoWriteCommand, MongoWriteOutcome, OperationData, PlanData, PlanOptions, ProfileData, ProfileOptions, ProfileUpdateOptions, ProfilesData, PurgeData, RedisCommand, RedisExecOptions, RedisPlanOptions, RedisQueryOptions, RedisWriteOutcome, QueryOptions, RecentOperationData, RecentResultData, RemovedProfileData, Response, ResultData, RollbackTransactionData, Row, RowsData, RowsOptions, SqlParameters, SqlDriver, StateQLActorOptions, StateQLOptions, StateConfidence, StateQLSnapshot, StateQLSnapshotOptions, StatusConnectionData, StatusData, Success, SessionData, SessionListItem, SessionsData, SessionSummaryData, TransactionData, TransactionReferenceData, Warning, } from "./types.js";
|
|
5
|
+
export type { ActorData, ActorLinkData, ActorResolutionData, ActorsData, ActorUnlinkData, AliasData, ApplyData, BatchCommand, BatchCommandName, BatchOptions, CatalogObject, CatalogObjectKind, DescribeObjectData, ListObjectsData, ListObjectsFilter, CapabilitiesData, CommandExecutionContext, CommandOrigin, CloseSessionData, Column, ColumnsData, CommitTransactionData, ConnectOptions, ConnectionData, CountData, CredentialAccess, CredentialOperation, CredentialRequest, CredentialSource, CredentialResolver, DisconnectData, DoctorData, Driver, ExecData, ExecOptions, ExecutionOptions, ExportData, Failure, FilterOptions, HistoryData, HistoryEntry, HistoryCategory, HistoryOptions, MongoAggregateOptions, MongoDocument, MongoFindOptions, MongoMutationOptions, MongoExecOptions, MongoPlanOptions, MongoQueryOptions, MongoReadCommand, MongoWriteCommand, MongoWriteOutcome, OperationData, PlanData, PlanOptions, ProfileData, ProfileOptions, ProfileUpdateOptions, ProfilesData, PurgeData, RedisCommand, RedisExecOptions, RedisPlanOptions, RedisQueryOptions, RedisWriteOutcome, QueryOptions, RecentOperationData, RecentResultData, RemovedProfileData, Response, ResultData, RollbackTransactionData, Row, RowsData, RowsOptions, SqlParameters, SqlDriver, StateQLActorOptions, StateQLOptions, StateConfidence, StateQLSnapshot, StateQLSnapshotOptions, StateQLWorkspaceOptions, StatusConnectionData, StatusData, Success, SessionData, SessionListItem, SessionsData, SessionSummaryData, TransactionData, TransactionReferenceData, Warning, } from "./types.js";
|
package/dist/src/stateql.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type TableChange } from "./table-editor.js";
|
|
2
|
-
import type { ActorLinkData, ActorResolutionData, ActorsData, ActorUnlinkData, AliasData, ApplyData, BatchCommand, CommandExecutionContext, CommandOrigin, BatchOptions, CapabilitiesData, CatalogObject, DescribeObjectData, ListObjectsData, ListObjectsFilter, CloseSessionData, ColumnsData, CommitTransactionData, ConnectOptions, ConnectionData, CountData, DisconnectData, DoctorData, ExecData, ExecOptions, ExecutionOptions, ExportData, FilterOptions, HistoryData, HistoryOptions, OperationData, PlanData, PlanOptions, ProfileData, ProfilesData, ProfileOptions, ProfileUpdateOptions, MongoExecOptions, MongoPlanOptions, MongoQueryOptions, MongoReadCommand, MongoWriteCommand, RedisCommand, RedisExecOptions, RedisPlanOptions, RedisQueryOptions, PurgeData, QueryOptions, RemovedProfileData, Response, ResultData, RollbackTransactionData, RowsData, RowsOptions, Column, StateQLActorOptions, StateQLOptions, StateQLSnapshot, StateQLSnapshotOptions, StatusData, SessionData, SessionsData, SessionSummaryData, TransactionData } from "./types.js";
|
|
2
|
+
import type { ActorLinkData, ActorResolutionData, ActorsData, ActorUnlinkData, AliasData, ApplyData, BatchCommand, CommandExecutionContext, CommandOrigin, BatchOptions, CapabilitiesData, CatalogObject, DescribeObjectData, ListObjectsData, ListObjectsFilter, CloseSessionData, ColumnsData, CommitTransactionData, ConnectOptions, ConnectionData, CountData, DisconnectData, DoctorData, ExecData, ExecOptions, ExecutionOptions, ExportData, FilterOptions, HistoryData, HistoryOptions, OperationData, PlanData, PlanOptions, ProfileData, ProfilesData, ProfileOptions, ProfileUpdateOptions, MongoExecOptions, MongoPlanOptions, MongoQueryOptions, MongoReadCommand, MongoWriteCommand, RedisCommand, RedisExecOptions, RedisPlanOptions, RedisQueryOptions, PurgeData, QueryOptions, RemovedProfileData, Response, ResultData, RollbackTransactionData, RowsData, RowsOptions, Column, StateQLActorOptions, StateQLOptions, StateQLWorkspaceOptions, StateQLSnapshot, StateQLSnapshotOptions, StatusData, SessionData, SessionsData, SessionSummaryData, TransactionData } from "./types.js";
|
|
3
3
|
export declare class StateQL {
|
|
4
4
|
/** Runtime contract marker for passwordRef/password_ref support. */
|
|
5
5
|
static readonly passwordReferenceVersion: 1;
|
|
6
6
|
static forActor(options: StateQLActorOptions): StateQL;
|
|
7
|
+
/** Opens one actor in a named shared workspace for a trusted library host. */
|
|
8
|
+
static forWorkspace(options: StateQLWorkspaceOptions): StateQL;
|
|
7
9
|
private readonly store;
|
|
8
10
|
private readonly sessionName;
|
|
9
11
|
private readonly actorId;
|
package/dist/src/stateql.js
CHANGED
|
@@ -17,6 +17,7 @@ import { compactRows, defaultHome, hash, isSqlParameters, parseJson, redact, } f
|
|
|
17
17
|
const DEFAULT_SNAPSHOT_HISTORY_LIMIT = 50;
|
|
18
18
|
const MAX_SNAPSHOT_HISTORY_LIMIT = 100;
|
|
19
19
|
const DEFAULT_CREDENTIAL_RESOLUTION_TIMEOUT_MS = 120_000;
|
|
20
|
+
const WORKSPACE_BOOTSTRAP = Symbol("StateQL.workspaceBootstrap");
|
|
20
21
|
export class StateQL {
|
|
21
22
|
/** Runtime contract marker for passwordRef/password_ref support. */
|
|
22
23
|
static passwordReferenceVersion = 1;
|
|
@@ -37,6 +38,21 @@ export class StateQL {
|
|
|
37
38
|
store.close();
|
|
38
39
|
}
|
|
39
40
|
}
|
|
41
|
+
/** Opens one actor in a named shared workspace for a trusted library host. */
|
|
42
|
+
static forWorkspace(options) {
|
|
43
|
+
if (!options.workspace.trim()) {
|
|
44
|
+
throw new StateQLError("INVALID_COMMAND", "Workspace name is required.");
|
|
45
|
+
}
|
|
46
|
+
if (!options.actor.trim()) {
|
|
47
|
+
throw new StateQLError("INVALID_COMMAND", "Actor ID is required.");
|
|
48
|
+
}
|
|
49
|
+
const { workspace, ...actorOptions } = options;
|
|
50
|
+
return new StateQL({
|
|
51
|
+
...actorOptions,
|
|
52
|
+
session: workspace,
|
|
53
|
+
[WORKSPACE_BOOTSTRAP]: true,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
40
56
|
store;
|
|
41
57
|
sessionName;
|
|
42
58
|
actorId;
|
|
@@ -80,7 +96,12 @@ export class StateQL {
|
|
|
80
96
|
}
|
|
81
97
|
const store = new StateStore(options.home ?? defaultHome(), this.now, maxStateBytes);
|
|
82
98
|
try {
|
|
83
|
-
|
|
99
|
+
if (options[WORKSPACE_BOOTSTRAP]) {
|
|
100
|
+
store.bootstrapWorkspace(this.sessionName, this.actorId);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
store.bootstrapSession(this.sessionName, this.actorId, options.actor === undefined);
|
|
104
|
+
}
|
|
84
105
|
}
|
|
85
106
|
catch (error) {
|
|
86
107
|
store.close();
|
package/dist/src/store.d.ts
CHANGED
|
@@ -132,6 +132,7 @@ export declare class StateStore {
|
|
|
132
132
|
private insertWithRandomId;
|
|
133
133
|
ensureSession(name?: string): SessionRecord;
|
|
134
134
|
bootstrapSession(name: string, actorId: string, ensureLegacyMembership: boolean): SessionRecord;
|
|
135
|
+
bootstrapWorkspace(name: string, actorId: string): SessionRecord;
|
|
135
136
|
createSession(name: string): SessionRecord;
|
|
136
137
|
isSessionMember(sessionId: string, actorId: string): boolean;
|
|
137
138
|
linkActor(sessionId: string, requestingActorId: string, actorId: string): "linked" | "already_linked" | "actor_conflict" | "denied";
|
package/dist/src/store.js
CHANGED
|
@@ -132,6 +132,56 @@ export class StateStore {
|
|
|
132
132
|
throw error;
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
+
bootstrapWorkspace(name, actorId) {
|
|
136
|
+
const timestamp = this.now().toISOString();
|
|
137
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
138
|
+
try {
|
|
139
|
+
let row = this.db
|
|
140
|
+
.prepare("SELECT id, status FROM sessions WHERE name = ? LIMIT 1")
|
|
141
|
+
.get(name);
|
|
142
|
+
const identities = actorId === name ? [actorId] : [name, actorId];
|
|
143
|
+
for (const identity of identities) {
|
|
144
|
+
const existing = this.resolveActor(identity);
|
|
145
|
+
if (existing && existing.id !== row?.id) {
|
|
146
|
+
throw new StateQLError("PERMISSION_DENIED", `Actor "${identity}" is already attached to workspace "${existing.name}" and cannot be attached to workspace "${name}".`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!row) {
|
|
150
|
+
const id = this.insertWithRandomId("s", "sessions", (candidate) => {
|
|
151
|
+
this.db
|
|
152
|
+
.prepare(`INSERT INTO sessions
|
|
153
|
+
(id, name, status, created_at, updated_at)
|
|
154
|
+
VALUES (?, ?, 'active', ?, ?)`)
|
|
155
|
+
.run(candidate, name, timestamp, timestamp);
|
|
156
|
+
});
|
|
157
|
+
row = { id, status: "active" };
|
|
158
|
+
}
|
|
159
|
+
else if (row.status !== "active") {
|
|
160
|
+
this.db
|
|
161
|
+
.prepare(`UPDATE sessions
|
|
162
|
+
SET status = 'active', updated_at = ?
|
|
163
|
+
WHERE id = ?`)
|
|
164
|
+
.run(timestamp, row.id);
|
|
165
|
+
}
|
|
166
|
+
for (const identity of identities) {
|
|
167
|
+
if (this.isSessionMember(row.id, identity))
|
|
168
|
+
continue;
|
|
169
|
+
this.db
|
|
170
|
+
.prepare(`INSERT INTO session_members(session_id, actor_id, attached_at)
|
|
171
|
+
VALUES (?, ?, ?)`)
|
|
172
|
+
.run(row.id, identity, timestamp);
|
|
173
|
+
}
|
|
174
|
+
const session = this.getSessionByName(name);
|
|
175
|
+
if (!session)
|
|
176
|
+
throw new Error(`Could not open workspace "${name}".`);
|
|
177
|
+
this.db.exec("COMMIT");
|
|
178
|
+
return session;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
this.db.exec("ROLLBACK");
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
135
185
|
createSession(name) {
|
|
136
186
|
return this.bootstrapSession(name, name, true);
|
|
137
187
|
}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -274,6 +274,10 @@ export interface StateQLOptions extends ExecutionOptions {
|
|
|
274
274
|
export type StateQLActorOptions = Omit<StateQLOptions, "session" | "actor"> & {
|
|
275
275
|
actor: string;
|
|
276
276
|
};
|
|
277
|
+
/** Trusted-host options for opening one actor in a named shared workspace. */
|
|
278
|
+
export type StateQLWorkspaceOptions = StateQLActorOptions & {
|
|
279
|
+
workspace: string;
|
|
280
|
+
};
|
|
277
281
|
export interface QueryOptions extends ExecutionOptions {
|
|
278
282
|
params?: SqlParameters;
|
|
279
283
|
cache?: "auto" | "bypass" | "require";
|