solid-objects 0.12.1 → 0.13.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/CHANGELOG.md +38 -0
- package/README.md +228 -953
- package/dist/actor.d.ts +12 -0
- package/dist/actor.d.ts.map +1 -1
- package/dist/actor.js +25 -2
- package/dist/actor.js.map +1 -1
- package/dist/browser/components.d.ts.map +1 -1
- package/dist/browser/components.js +4 -1
- package/dist/browser/components.js.map +1 -1
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +8 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -1
- package/dist/cli.js.map +1 -1
- package/dist/configuration.d.ts +1 -0
- package/dist/configuration.d.ts.map +1 -1
- package/dist/configuration.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +12 -3
- package/dist/doctor.js.map +1 -1
- package/dist/examples/sqlite-quickstart.js +83 -0
- package/dist/examples/sqlite-quickstart.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/records.d.ts +1 -0
- package/dist/records.d.ts.map +1 -1
- package/dist/repository.d.ts +4 -1
- package/dist/repository.d.ts.map +1 -1
- package/dist/repository.js +5 -4
- package/dist/repository.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +37 -6
- package/dist/runtime.js.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +15 -4
- package/dist/schema.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web/assets.d.ts +4 -0
- package/dist/web/assets.d.ts.map +1 -0
- package/dist/web/assets.js +11 -0
- package/dist/web/assets.js.map +1 -0
- package/dist/web/index.d.ts +28 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +642 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/node.d.ts +3 -0
- package/dist/web/node.d.ts.map +1 -0
- package/dist/web/node.js +109 -0
- package/dist/web/node.js.map +1 -0
- package/dist/web/render.d.ts +64 -0
- package/dist/web/render.d.ts.map +1 -0
- package/dist/web/render.js +331 -0
- package/dist/web/render.js.map +1 -0
- package/dist/web/store.d.ts +65 -0
- package/dist/web/store.d.ts.map +1 -0
- package/dist/web/store.js +303 -0
- package/dist/web/store.js.map +1 -0
- package/dist/web/types.d.ts +82 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +2 -0
- package/dist/web/types.js.map +1 -0
- package/docs/api.md +63 -0
- package/docs/architecture.md +16 -10
- package/docs/authorization.md +12 -3
- package/docs/benchmarks.md +123 -0
- package/docs/browser-protocol.md +15 -8
- package/docs/comparisons.md +36 -0
- package/docs/configuration.md +3 -1
- package/docs/correctness.md +23 -0
- package/docs/dashboard.md +196 -0
- package/docs/fit.md +58 -0
- package/docs/parity.md +37 -34
- package/docs/releasing.md +6 -4
- package/docs/state-and-lifecycle.md +10 -0
- package/docs/support.md +39 -0
- package/examples/failure-recovery/actor.ts +51 -0
- package/examples/failure-recovery/demo.ts +233 -0
- package/examples/failure-recovery/worker.ts +46 -0
- package/examples/sqlite-quickstart.ts +109 -0
- package/package.json +25 -4
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SolidObjectsRuntime } from "../runtime.js";
|
|
2
|
+
export type DashboardRecord = Record<string, unknown>;
|
|
3
|
+
export interface DashboardPageResult {
|
|
4
|
+
readonly records: readonly DashboardRecord[];
|
|
5
|
+
readonly page: number;
|
|
6
|
+
readonly perPage: number;
|
|
7
|
+
readonly total: number;
|
|
8
|
+
readonly lastPage: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DashboardStatistics extends DashboardRecord {
|
|
11
|
+
readonly instances: DashboardRecord;
|
|
12
|
+
readonly mailbox: DashboardRecord;
|
|
13
|
+
readonly effects: DashboardRecord;
|
|
14
|
+
readonly broadcasts: DashboardRecord;
|
|
15
|
+
readonly reminders: DashboardRecord;
|
|
16
|
+
readonly deadLetters: DashboardRecord;
|
|
17
|
+
readonly processes: DashboardRecord;
|
|
18
|
+
readonly serverTime: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DashboardInstanceDetail {
|
|
21
|
+
readonly instance: DashboardRecord;
|
|
22
|
+
readonly readyMessages: readonly DashboardRecord[];
|
|
23
|
+
readonly claimedMessages: readonly DashboardRecord[];
|
|
24
|
+
readonly recentMessages: readonly DashboardRecord[];
|
|
25
|
+
readonly reminders: readonly DashboardRecord[];
|
|
26
|
+
readonly effects: readonly DashboardRecord[];
|
|
27
|
+
readonly broadcasts: readonly DashboardRecord[];
|
|
28
|
+
readonly deadLetters: readonly DashboardRecord[];
|
|
29
|
+
}
|
|
30
|
+
interface PageOptions {
|
|
31
|
+
readonly page?: string | null;
|
|
32
|
+
readonly perPage?: string | null;
|
|
33
|
+
readonly status?: string | null;
|
|
34
|
+
readonly actorType?: string | null;
|
|
35
|
+
readonly actorId?: string | null;
|
|
36
|
+
readonly membership?: string | null;
|
|
37
|
+
}
|
|
38
|
+
export declare class DashboardStore {
|
|
39
|
+
private readonly runtime;
|
|
40
|
+
constructor(runtime: SolidObjectsRuntime);
|
|
41
|
+
statistics(): Promise<DashboardStatistics>;
|
|
42
|
+
instances(options: PageOptions): Promise<DashboardPageResult>;
|
|
43
|
+
mailbox(options: PageOptions): Promise<DashboardPageResult>;
|
|
44
|
+
reminders(options: PageOptions): Promise<DashboardPageResult>;
|
|
45
|
+
effects(options: PageOptions): Promise<DashboardPageResult>;
|
|
46
|
+
broadcasts(options: PageOptions): Promise<DashboardPageResult>;
|
|
47
|
+
deadLetters(options: PageOptions): Promise<DashboardPageResult>;
|
|
48
|
+
processes(options: PageOptions): Promise<DashboardPageResult>;
|
|
49
|
+
instance(id: string): Promise<DashboardInstanceDetail | undefined>;
|
|
50
|
+
message(id: string): Promise<DashboardRecord | undefined>;
|
|
51
|
+
deadLetter(id: string): Promise<DashboardRecord | undefined>;
|
|
52
|
+
dashboard(): Promise<DashboardRecord>;
|
|
53
|
+
setPaused(options: {
|
|
54
|
+
id: string;
|
|
55
|
+
paused: boolean;
|
|
56
|
+
}): Promise<boolean>;
|
|
57
|
+
healthy(): Promise<void>;
|
|
58
|
+
private page;
|
|
59
|
+
private statusPage;
|
|
60
|
+
private grouped;
|
|
61
|
+
private substringExpression;
|
|
62
|
+
private table;
|
|
63
|
+
}
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/web/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
const EFFECT_STATUSES = ["pending", "processing", "completed", "dead"];
|
|
2
|
+
const BROADCAST_STATUSES = ["pending", "processing", "delivered", "dead"];
|
|
3
|
+
const REMINDER_STATUSES = ["scheduled", "paused", "completed"];
|
|
4
|
+
const PROCESS_STATUSES = ["running", "draining", "stopped"];
|
|
5
|
+
export class DashboardStore {
|
|
6
|
+
runtime;
|
|
7
|
+
constructor(runtime) {
|
|
8
|
+
this.runtime = runtime;
|
|
9
|
+
}
|
|
10
|
+
async statistics() {
|
|
11
|
+
return this.runtime.settings.database.connection(async (connection) => {
|
|
12
|
+
const now = await connection.nowMilliseconds();
|
|
13
|
+
const [instances, mailbox, effects, broadcasts, reminders, deadLetters, processes] = await Promise.all([
|
|
14
|
+
connection.get(`SELECT COUNT(*) AS total,
|
|
15
|
+
SUM(CASE WHEN paused = 1 THEN 1 ELSE 0 END) AS paused,
|
|
16
|
+
SUM(CASE WHEN activation_expires_at_ms >= ? THEN 1 ELSE 0 END) AS activated
|
|
17
|
+
FROM ${this.table("instances")}`, [now]),
|
|
18
|
+
connection.get(`SELECT COUNT(*) AS ready,
|
|
19
|
+
SUM(CASE WHEN available_at_ms <= ? THEN 1 ELSE 0 END) AS due,
|
|
20
|
+
MIN(CASE WHEN available_at_ms <= ? THEN available_at_ms END) AS oldest_due
|
|
21
|
+
FROM ${this.table("ready_messages")}`, [now, now]),
|
|
22
|
+
this.grouped({
|
|
23
|
+
connection,
|
|
24
|
+
table: "effects",
|
|
25
|
+
column: "status",
|
|
26
|
+
statuses: EFFECT_STATUSES,
|
|
27
|
+
}),
|
|
28
|
+
this.grouped({
|
|
29
|
+
connection,
|
|
30
|
+
table: "broadcasts",
|
|
31
|
+
column: "status",
|
|
32
|
+
statuses: BROADCAST_STATUSES,
|
|
33
|
+
}),
|
|
34
|
+
this.grouped({
|
|
35
|
+
connection,
|
|
36
|
+
table: "reminders",
|
|
37
|
+
column: "status",
|
|
38
|
+
statuses: REMINDER_STATUSES,
|
|
39
|
+
}),
|
|
40
|
+
connection.get(`SELECT COUNT(*) AS total FROM ${this.table("dead_letters")}`),
|
|
41
|
+
this.grouped({
|
|
42
|
+
connection,
|
|
43
|
+
table: "processes",
|
|
44
|
+
column: "shutdown_state",
|
|
45
|
+
statuses: PROCESS_STATUSES,
|
|
46
|
+
}),
|
|
47
|
+
]);
|
|
48
|
+
const claimed = await connection.get(`SELECT COUNT(*) AS total FROM ${this.table("claimed_messages")}`);
|
|
49
|
+
const reminderDue = await connection.get(`SELECT COUNT(*) AS total FROM ${this.table("reminders")}
|
|
50
|
+
WHERE status = 'scheduled' AND run_at_ms <= ?`, [now]);
|
|
51
|
+
const oldestDue = numeric(mailbox?.oldest_due);
|
|
52
|
+
return freezeRecord({
|
|
53
|
+
instances: freezeRecord({
|
|
54
|
+
total: numeric(instances?.total),
|
|
55
|
+
paused: numeric(instances?.paused),
|
|
56
|
+
activated: numeric(instances?.activated),
|
|
57
|
+
}),
|
|
58
|
+
mailbox: freezeRecord({
|
|
59
|
+
ready: numeric(mailbox?.ready),
|
|
60
|
+
due: numeric(mailbox?.due),
|
|
61
|
+
claimed: numeric(claimed?.total),
|
|
62
|
+
latency: oldestDue === 0 ? 0 : Math.max(0, (now - oldestDue) / 1_000),
|
|
63
|
+
}),
|
|
64
|
+
effects,
|
|
65
|
+
broadcasts,
|
|
66
|
+
reminders: freezeRecord({ ...reminders, due: numeric(reminderDue?.total) }),
|
|
67
|
+
deadLetters: freezeRecord({ total: numeric(deadLetters?.total) }),
|
|
68
|
+
processes,
|
|
69
|
+
serverTime: new Date(now).toISOString(),
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
instances(options) {
|
|
74
|
+
const conditions = [];
|
|
75
|
+
const parameters = [];
|
|
76
|
+
if (options.actorType) {
|
|
77
|
+
conditions.push("actor_type = ?");
|
|
78
|
+
parameters.push(options.actorType);
|
|
79
|
+
}
|
|
80
|
+
if (options.actorId) {
|
|
81
|
+
const expression = this.substringExpression("actor_id");
|
|
82
|
+
conditions.push(expression);
|
|
83
|
+
parameters.push(options.actorId);
|
|
84
|
+
}
|
|
85
|
+
return this.page({
|
|
86
|
+
from: this.table("instances"),
|
|
87
|
+
...(conditions.length === 0 ? {} : { where: conditions.join(" AND ") }),
|
|
88
|
+
parameters,
|
|
89
|
+
order: "updated_at_ms DESC, id DESC",
|
|
90
|
+
}, options);
|
|
91
|
+
}
|
|
92
|
+
mailbox(options) {
|
|
93
|
+
const membership = options.membership === "claimed" ? "claimed_messages" : "ready_messages";
|
|
94
|
+
const timeColumn = membership === "claimed_messages" ? "membership.claimed_at_ms" : "membership.available_at_ms";
|
|
95
|
+
return this.page({
|
|
96
|
+
from: `${this.table("messages")} messages
|
|
97
|
+
INNER JOIN ${this.table(membership)} membership ON membership.message_id = messages.id`,
|
|
98
|
+
order: `${timeColumn} ASC, messages.id ASC`,
|
|
99
|
+
}, options);
|
|
100
|
+
}
|
|
101
|
+
reminders(options) {
|
|
102
|
+
return this.statusPage({
|
|
103
|
+
table: "reminders",
|
|
104
|
+
statuses: REMINDER_STATUSES,
|
|
105
|
+
order: "run_at_ms ASC, id ASC",
|
|
106
|
+
options,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
effects(options) {
|
|
110
|
+
return this.statusPage({
|
|
111
|
+
table: "effects",
|
|
112
|
+
statuses: EFFECT_STATUSES,
|
|
113
|
+
order: "available_at_ms DESC, id DESC",
|
|
114
|
+
options,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
broadcasts(options) {
|
|
118
|
+
return this.statusPage({
|
|
119
|
+
table: "broadcasts",
|
|
120
|
+
statuses: BROADCAST_STATUSES,
|
|
121
|
+
order: "available_at_ms DESC, id DESC",
|
|
122
|
+
options,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
deadLetters(options) {
|
|
126
|
+
return this.page({
|
|
127
|
+
from: `${this.table("dead_letters")} dead_letters
|
|
128
|
+
INNER JOIN ${this.table("messages")} messages ON messages.id = dead_letters.message_id`,
|
|
129
|
+
select: "dead_letters.id, dead_letters.message_id, dead_letters.instance_id, dead_letters.attempts, dead_letters.error, dead_letters.created_at_ms, dead_letters.retried_message_id, messages.actor_type, messages.actor_id, messages.operation, messages.delivery_mode, messages.arguments",
|
|
130
|
+
order: "dead_letters.created_at_ms DESC, dead_letters.id DESC",
|
|
131
|
+
}, options);
|
|
132
|
+
}
|
|
133
|
+
processes(options) {
|
|
134
|
+
return this.statusPage({
|
|
135
|
+
table: "processes",
|
|
136
|
+
statusColumn: "shutdown_state",
|
|
137
|
+
statuses: PROCESS_STATUSES,
|
|
138
|
+
order: "heartbeat_at_ms DESC, id DESC",
|
|
139
|
+
options,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async instance(id) {
|
|
143
|
+
return this.runtime.settings.database.connection(async (connection) => {
|
|
144
|
+
const instance = await connection.get(`SELECT * FROM ${this.table("instances")} WHERE id = ?`, [id]);
|
|
145
|
+
if (!instance)
|
|
146
|
+
return undefined;
|
|
147
|
+
const related = { instanceId: id, limit: 10 };
|
|
148
|
+
const [readyMessages, claimedMessages, recentMessages, reminders, effects, broadcasts, deadLetters,] = await Promise.all([
|
|
149
|
+
connection.all(`SELECT messages.*, membership.available_at_ms
|
|
150
|
+
FROM ${this.table("messages")} messages
|
|
151
|
+
INNER JOIN ${this.table("ready_messages")} membership ON membership.message_id = messages.id
|
|
152
|
+
WHERE messages.instance_id = ? ORDER BY messages.sequence ASC LIMIT ?`, [related.instanceId, related.limit]),
|
|
153
|
+
connection.all(`SELECT messages.*, membership.claimed_at_ms
|
|
154
|
+
FROM ${this.table("messages")} messages
|
|
155
|
+
INNER JOIN ${this.table("claimed_messages")} membership ON membership.message_id = messages.id
|
|
156
|
+
WHERE messages.instance_id = ? ORDER BY messages.sequence ASC LIMIT ?`, [related.instanceId, related.limit]),
|
|
157
|
+
connection.all(`SELECT * FROM ${this.table("messages")} WHERE instance_id = ?
|
|
158
|
+
ORDER BY sequence DESC LIMIT ?`, [related.instanceId, related.limit]),
|
|
159
|
+
connection.all(`SELECT * FROM ${this.table("reminders")} WHERE instance_id = ?
|
|
160
|
+
ORDER BY run_at_ms ASC LIMIT ?`, [related.instanceId, related.limit]),
|
|
161
|
+
connection.all(`SELECT * FROM ${this.table("effects")} WHERE instance_id = ?
|
|
162
|
+
ORDER BY available_at_ms DESC LIMIT ?`, [related.instanceId, related.limit]),
|
|
163
|
+
connection.all(`SELECT * FROM ${this.table("broadcasts")} WHERE instance_id = ?
|
|
164
|
+
ORDER BY available_at_ms DESC LIMIT ?`, [related.instanceId, related.limit]),
|
|
165
|
+
connection.all(`SELECT dead_letters.*, messages.actor_type, messages.actor_id, messages.operation,
|
|
166
|
+
messages.delivery_mode, messages.arguments
|
|
167
|
+
FROM ${this.table("dead_letters")} dead_letters
|
|
168
|
+
INNER JOIN ${this.table("messages")} messages ON messages.id = dead_letters.message_id
|
|
169
|
+
WHERE dead_letters.instance_id = ? ORDER BY dead_letters.created_at_ms DESC LIMIT ?`, [related.instanceId, related.limit]),
|
|
170
|
+
]);
|
|
171
|
+
return Object.freeze({
|
|
172
|
+
instance: freezeRecord(instance),
|
|
173
|
+
readyMessages: freezeRecords(readyMessages),
|
|
174
|
+
claimedMessages: freezeRecords(claimedMessages),
|
|
175
|
+
recentMessages: freezeRecords(recentMessages),
|
|
176
|
+
reminders: freezeRecords(reminders),
|
|
177
|
+
effects: freezeRecords(effects),
|
|
178
|
+
broadcasts: freezeRecords(broadcasts),
|
|
179
|
+
deadLetters: freezeRecords(deadLetters),
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
message(id) {
|
|
184
|
+
return this.runtime.settings.database.connection(async (connection) => {
|
|
185
|
+
const record = await connection.get(`SELECT messages.*,
|
|
186
|
+
CASE WHEN ready.message_id IS NOT NULL THEN 'ready'
|
|
187
|
+
WHEN claimed.message_id IS NOT NULL THEN 'claimed'
|
|
188
|
+
WHEN messages.completed_at_ms IS NOT NULL THEN 'completed'
|
|
189
|
+
ELSE 'history' END AS membership
|
|
190
|
+
FROM ${this.table("messages")} messages
|
|
191
|
+
LEFT JOIN ${this.table("ready_messages")} ready ON ready.message_id = messages.id
|
|
192
|
+
LEFT JOIN ${this.table("claimed_messages")} claimed ON claimed.message_id = messages.id
|
|
193
|
+
WHERE messages.id = ?`, [id]);
|
|
194
|
+
return record ? freezeRecord(record) : undefined;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
deadLetter(id) {
|
|
198
|
+
return this.runtime.settings.database.connection(async (connection) => {
|
|
199
|
+
const record = await connection.get(`SELECT dead_letters.*, messages.actor_type, messages.actor_id, messages.operation,
|
|
200
|
+
messages.delivery_mode, messages.arguments
|
|
201
|
+
FROM ${this.table("dead_letters")} dead_letters
|
|
202
|
+
INNER JOIN ${this.table("messages")} messages ON messages.id = dead_letters.message_id
|
|
203
|
+
WHERE dead_letters.id = ?`, [id]);
|
|
204
|
+
return record ? freezeRecord(record) : undefined;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
async dashboard() {
|
|
208
|
+
return this.runtime.settings.database.connection(async (connection) => {
|
|
209
|
+
const [processes, deadLetters, instancesByType] = await Promise.all([
|
|
210
|
+
connection.all(`SELECT * FROM ${this.table("processes")} ORDER BY heartbeat_at_ms DESC LIMIT 10`),
|
|
211
|
+
connection.all(`SELECT dead_letters.*, messages.actor_type, messages.actor_id, messages.operation
|
|
212
|
+
FROM ${this.table("dead_letters")} dead_letters
|
|
213
|
+
INNER JOIN ${this.table("messages")} messages ON messages.id = dead_letters.message_id
|
|
214
|
+
ORDER BY dead_letters.created_at_ms DESC LIMIT 10`),
|
|
215
|
+
connection.all(`SELECT actor_type, COUNT(*) AS count FROM ${this.table("instances")}
|
|
216
|
+
GROUP BY actor_type ORDER BY count DESC LIMIT 12`),
|
|
217
|
+
]);
|
|
218
|
+
return freezeRecord({
|
|
219
|
+
processes: freezeRecords(processes),
|
|
220
|
+
deadLetters: freezeRecords(deadLetters),
|
|
221
|
+
instancesByType: freezeRecords(instancesByType),
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async setPaused(options) {
|
|
226
|
+
const result = await this.runtime.settings.database.transaction(async (connection) => {
|
|
227
|
+
const now = await connection.nowMilliseconds();
|
|
228
|
+
return connection.run(`UPDATE ${this.table("instances")} SET paused = ?, updated_at_ms = ? WHERE id = ?`, [options.paused, now, options.id]);
|
|
229
|
+
});
|
|
230
|
+
return result.changes > 0;
|
|
231
|
+
}
|
|
232
|
+
async healthy() {
|
|
233
|
+
await this.runtime.settings.database.connection((connection) => connection.get(`SELECT 1 AS healthy FROM ${this.table("schema_migrations")} LIMIT 1`));
|
|
234
|
+
}
|
|
235
|
+
async page(query, options) {
|
|
236
|
+
const perPage = boundedInteger(options.perPage, { fallback: 25, maximum: 200 });
|
|
237
|
+
return this.runtime.settings.database.connection(async (connection) => {
|
|
238
|
+
const where = query.where ? ` WHERE ${query.where}` : "";
|
|
239
|
+
const parameters = [...(query.parameters ?? [])];
|
|
240
|
+
const count = await connection.get(`SELECT COUNT(*) AS count FROM ${query.from}${where}`, parameters);
|
|
241
|
+
const total = numeric(count?.count);
|
|
242
|
+
const lastPage = Math.max(Math.ceil(total / perPage), 1);
|
|
243
|
+
const page = Math.min(boundedInteger(options.page, { fallback: 1, maximum: lastPage }), lastPage);
|
|
244
|
+
const records = await connection.all(`SELECT ${query.select ?? "*"} FROM ${query.from}${where} ORDER BY ${query.order} LIMIT ? OFFSET ?`, [...parameters, perPage, (page - 1) * perPage]);
|
|
245
|
+
return Object.freeze({
|
|
246
|
+
records: freezeRecords(records),
|
|
247
|
+
page,
|
|
248
|
+
perPage,
|
|
249
|
+
total,
|
|
250
|
+
lastPage,
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
statusPage(options) {
|
|
255
|
+
const status = options.statuses.includes(options.options.status ?? "")
|
|
256
|
+
? options.options.status
|
|
257
|
+
: undefined;
|
|
258
|
+
const statusColumn = options.statusColumn ?? "status";
|
|
259
|
+
return this.page({
|
|
260
|
+
from: this.table(options.table),
|
|
261
|
+
...(status ? { where: `${statusColumn} = ?`, parameters: [status] } : {}),
|
|
262
|
+
order: options.order,
|
|
263
|
+
}, options.options);
|
|
264
|
+
}
|
|
265
|
+
async grouped(options) {
|
|
266
|
+
const { connection, table, column, statuses } = options;
|
|
267
|
+
const rows = await connection.all(`SELECT ${column} AS status, COUNT(*) AS count FROM ${this.table(table)} GROUP BY ${column}`);
|
|
268
|
+
const counts = new Map(rows.map((row) => [row.status, numeric(row.count)]));
|
|
269
|
+
return freezeRecord(Object.fromEntries(statuses.map((status) => [status, counts.get(status) ?? 0])));
|
|
270
|
+
}
|
|
271
|
+
substringExpression(column) {
|
|
272
|
+
if (this.runtime.settings.database.family === "sqlite")
|
|
273
|
+
return `instr(${column}, ?) > 0`;
|
|
274
|
+
if (this.runtime.settings.database.family === "postgresql")
|
|
275
|
+
return `POSITION(? IN ${column}) > 0`;
|
|
276
|
+
return `LOCATE(?, ${column}) > 0`;
|
|
277
|
+
}
|
|
278
|
+
table(name) {
|
|
279
|
+
return this.runtime.repository.table(name);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function boundedInteger(value, options) {
|
|
283
|
+
const parsed = Number.parseInt(value ?? "", 10);
|
|
284
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1)
|
|
285
|
+
return options.fallback;
|
|
286
|
+
return Math.min(parsed, options.maximum);
|
|
287
|
+
}
|
|
288
|
+
function numeric(value) {
|
|
289
|
+
if (typeof value === "number")
|
|
290
|
+
return value;
|
|
291
|
+
if (typeof value === "bigint")
|
|
292
|
+
return Number(value);
|
|
293
|
+
if (typeof value === "string")
|
|
294
|
+
return Number(value);
|
|
295
|
+
return 0;
|
|
296
|
+
}
|
|
297
|
+
function freezeRecord(record) {
|
|
298
|
+
return Object.freeze(record);
|
|
299
|
+
}
|
|
300
|
+
function freezeRecords(records) {
|
|
301
|
+
return Object.freeze(records.map(freezeRecord));
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/web/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { SolidObjectsRuntime } from "../runtime.js";
|
|
3
|
+
export interface DashboardSession {
|
|
4
|
+
read(key: string): string | undefined | Promise<string | undefined>;
|
|
5
|
+
write(key: string, value: string): void | Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface DashboardRequestContext {
|
|
8
|
+
readonly authorizationContext?: unknown;
|
|
9
|
+
readonly session?: DashboardSession;
|
|
10
|
+
}
|
|
11
|
+
export type DashboardAccess = "authorized" | "authorized-read-only" | "public-read-only";
|
|
12
|
+
export interface DashboardPolicy {
|
|
13
|
+
readonly action: string;
|
|
14
|
+
readonly resource: string;
|
|
15
|
+
}
|
|
16
|
+
export interface DashboardPage {
|
|
17
|
+
readonly title: string;
|
|
18
|
+
readonly content: string;
|
|
19
|
+
readonly status?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface DashboardRenderInput {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly model: Readonly<Record<string, unknown>>;
|
|
24
|
+
readonly defaultHtml: string;
|
|
25
|
+
}
|
|
26
|
+
export type DashboardRenderer = (input: DashboardRenderInput) => string;
|
|
27
|
+
export interface DashboardRouteContext {
|
|
28
|
+
readonly request: Request;
|
|
29
|
+
readonly requestContext: DashboardRequestContext;
|
|
30
|
+
readonly params: Readonly<Record<string, string>>;
|
|
31
|
+
readonly runtime: SolidObjectsRuntime;
|
|
32
|
+
path(path: string): string;
|
|
33
|
+
render(page: DashboardPage): Response;
|
|
34
|
+
escape(value: unknown): string;
|
|
35
|
+
}
|
|
36
|
+
export interface DashboardRoute {
|
|
37
|
+
readonly method: "GET" | "HEAD" | "POST";
|
|
38
|
+
readonly path: string;
|
|
39
|
+
readonly policy: DashboardPolicy;
|
|
40
|
+
handle(context: DashboardRouteContext): DashboardPage | Response | Promise<DashboardPage | Response>;
|
|
41
|
+
}
|
|
42
|
+
export interface DashboardTab {
|
|
43
|
+
readonly label: string;
|
|
44
|
+
readonly path: string;
|
|
45
|
+
}
|
|
46
|
+
export interface DashboardExtension {
|
|
47
|
+
readonly tab?: DashboardTab;
|
|
48
|
+
readonly routes?: readonly DashboardRoute[];
|
|
49
|
+
readonly renderers?: Readonly<Record<string, DashboardRenderer>>;
|
|
50
|
+
readonly middleware?: readonly DashboardMiddleware[];
|
|
51
|
+
}
|
|
52
|
+
export interface DashboardMiddlewareInput {
|
|
53
|
+
readonly request: Request;
|
|
54
|
+
readonly requestContext: DashboardRequestContext;
|
|
55
|
+
}
|
|
56
|
+
export type DashboardMiddleware = (input: DashboardMiddlewareInput, next: () => Promise<Response>) => Promise<Response>;
|
|
57
|
+
export interface DashboardChartLibrary {
|
|
58
|
+
readonly url: string | null;
|
|
59
|
+
readonly integrity?: string | null;
|
|
60
|
+
}
|
|
61
|
+
export interface DashboardOptions {
|
|
62
|
+
readonly runtime: SolidObjectsRuntime;
|
|
63
|
+
readonly mountPath?: string;
|
|
64
|
+
readonly access?: DashboardAccess;
|
|
65
|
+
readonly chartLibrary?: DashboardChartLibrary;
|
|
66
|
+
readonly extensions?: readonly DashboardExtension[];
|
|
67
|
+
readonly middleware?: readonly DashboardMiddleware[];
|
|
68
|
+
}
|
|
69
|
+
export interface NodeDashboardRequestContextResolver {
|
|
70
|
+
(request: IncomingMessage): DashboardRequestContext | Promise<DashboardRequestContext>;
|
|
71
|
+
}
|
|
72
|
+
export interface NodeDashboardHandlerOptions {
|
|
73
|
+
readonly dashboard: SolidObjectsDashboardContract;
|
|
74
|
+
readonly resolveContext: NodeDashboardRequestContextResolver;
|
|
75
|
+
readonly maximumBodyBytes?: number;
|
|
76
|
+
}
|
|
77
|
+
export interface SolidObjectsDashboardContract {
|
|
78
|
+
readonly mountPath: string;
|
|
79
|
+
fetch(request: Request, context: DashboardRequestContext): Promise<Response>;
|
|
80
|
+
}
|
|
81
|
+
export type NodeDashboardHandler = (...argumentsValue: [IncomingMessage, ServerResponse, ((error?: unknown) => void)?]) => void;
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/web/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/web/types.ts"],"names":[],"mappings":""}
|
package/docs/api.md
CHANGED
|
@@ -16,6 +16,11 @@ generic signatures; this index explains the supported role of every export.
|
|
|
16
16
|
- `Actor`: base class providing `ref()`, `actorId`, `currentMessage`,
|
|
17
17
|
`observables()`, `reject()`, `emit()`, `commitAction()`, `schedule()`,
|
|
18
18
|
`sendTo()`, and protected lifecycle hooks.
|
|
19
|
+
- `broadcastValue(value)`: mark an observable so its changed value enters the
|
|
20
|
+
durable invalidation envelope.
|
|
21
|
+
- `broadcastInvalidation(value)`: compare the real observable value but put
|
|
22
|
+
only its name in the durable envelope when it changes.
|
|
23
|
+
- `ObservableBroadcast`: the immutable marker type returned by either helper.
|
|
19
24
|
- `VERSION`: running package version.
|
|
20
25
|
- `ActorClass`, `ActorReference`, `ActorMessageSender`, `ActorSnapshot`,
|
|
21
26
|
`ActorOperationNames`, `ActorQueryNames`, `StagedOperations`, and
|
|
@@ -31,6 +36,25 @@ generic signatures; this index explains the supported role of every export.
|
|
|
31
36
|
`PayloadBroadcasts`, and `PayloadBroadcastValue` describe actor-declared
|
|
32
37
|
transactional work and typed personalized projections.
|
|
33
38
|
|
|
39
|
+
`observables()` returns a flat object. Unwrapped values are invalidation-only:
|
|
40
|
+
their real values participate in change detection, but only their names enter
|
|
41
|
+
the durable envelope. Use an explicit marker when wire behavior matters:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
override observables(): Record<string, unknown> {
|
|
45
|
+
return {
|
|
46
|
+
version: broadcastValue(this.document.version),
|
|
47
|
+
sidebar: broadcastInvalidation(this.sidebarForCurrentState()),
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Both values must be JSON-compatible and are evaluated after each successful
|
|
53
|
+
turn. An invalidation-only value participates in change detection but is never
|
|
54
|
+
written to the broadcast outbox or invalidation envelope. The envelope carries
|
|
55
|
+
its name in `invalidations`, allowing component registries to refresh a
|
|
56
|
+
reauthorized endpoint without exposing the value.
|
|
57
|
+
|
|
34
58
|
`MessageReference` does not retain an invocation's authorization context.
|
|
35
59
|
Supply `authorizationContext` to each `status()`, `result()`, and `wait()` call;
|
|
36
60
|
the runtime reauthorizes the persisted operation every time. Durable results
|
|
@@ -90,6 +114,10 @@ The manager types are `DeadLetter`; `ReminderPage`, `ReminderPageOptions`,
|
|
|
90
114
|
`AdministrationOptions` carries the application-owned authorization context
|
|
91
115
|
for administration calls.
|
|
92
116
|
|
|
117
|
+
The packaged `solid-objects quickstart` command is config-free and runs the
|
|
118
|
+
SQLite example shipped in the npm artifact. Every other CLI command loads the
|
|
119
|
+
application runtime configured through `--config`.
|
|
120
|
+
|
|
93
121
|
`ProcessRecord.shutdownState` is `"running"`, `"draining"`, or `"stopped"`;
|
|
94
122
|
there is no separate `running` field. `RetentionResult.count` means eligible
|
|
95
123
|
rows for `preview()` and rows actually deleted for `prune()`.
|
|
@@ -124,6 +152,11 @@ rows for `preview()` and rows actually deleted for `prune()`.
|
|
|
124
152
|
`DatabaseConnection`, `DatabaseFamily`, and `RunResult` support custom database
|
|
125
153
|
and commit-action integration.
|
|
126
154
|
|
|
155
|
+
`BroadcastEvent.observables` contains changed value-broadcast projections.
|
|
156
|
+
`BroadcastEvent.invalidations` contains changed invalidation-only names. The
|
|
157
|
+
runtime always supplies the array; consumers should treat its absence from an
|
|
158
|
+
older or application-produced event as an empty array.
|
|
159
|
+
|
|
127
160
|
### Runtime extensions and manual workers
|
|
128
161
|
|
|
129
162
|
`runtime.registerComponent(factory, { count = 1 })` adds application-owned
|
|
@@ -225,5 +258,35 @@ and `SyncTimeoutWaitingOn` type timeout diagnostics. See
|
|
|
225
258
|
`ComponentRefreshFailure`, and `ComponentRegistryOptions`: framework-neutral
|
|
226
259
|
refresh contract types.
|
|
227
260
|
|
|
261
|
+
`InvalidationEnvelope.observables` contains values and
|
|
262
|
+
`InvalidationEnvelope.invalidations` contains names without values. The
|
|
263
|
+
component registry reacts to names in either location.
|
|
264
|
+
|
|
228
265
|
The wire format, trust boundary, revision rules, and component semantics are in
|
|
229
266
|
[Browser protocol](browser-protocol.md).
|
|
267
|
+
|
|
268
|
+
## `solid-objects/web`
|
|
269
|
+
|
|
270
|
+
- `createDashboard(options)` creates an immutable `SolidObjectsDashboard` with
|
|
271
|
+
a standard `fetch(request, context)` entry point.
|
|
272
|
+
- `createNodeDashboardHandler(options)` adapts the Fetch entry point to
|
|
273
|
+
`node:http` and Connect-compatible middleware.
|
|
274
|
+
- `DashboardOptions` selects the runtime, mount path, `DashboardAccess`, chart library,
|
|
275
|
+
`DashboardExtension` objects, and `DashboardMiddleware` functions.
|
|
276
|
+
- `DashboardRequestContext` supplies the existing administration authorization
|
|
277
|
+
context and an optional `DashboardSession`. Read/write access requires the
|
|
278
|
+
session so its `read()` and `write()` methods can hold the masked CSRF token
|
|
279
|
+
across requests; read-only modes do not create CSRF state.
|
|
280
|
+
- `DashboardRoute`, `DashboardRouteContext`, `DashboardPolicy`, `DashboardPage`,
|
|
281
|
+
and `DashboardTab` define extension pages. Every route requires a policy.
|
|
282
|
+
- `DashboardRenderer`, `DashboardRenderInput`, and `DashboardMiddlewareInput`
|
|
283
|
+
define immutable view overrides and middleware inputs.
|
|
284
|
+
- `DashboardChartLibrary` selects the CDN, a self-hosted script, or disabled
|
|
285
|
+
charts.
|
|
286
|
+
- `NodeDashboardHandler`, `NodeDashboardHandlerOptions`, and
|
|
287
|
+
`NodeDashboardRequestContextResolver` describe the Node adapter.
|
|
288
|
+
- `SolidObjectsDashboardContract` is the minimal Fetch contract accepted by the
|
|
289
|
+
Node adapter.
|
|
290
|
+
|
|
291
|
+
Mounting, authorization actions, CSRF behavior, pages, and extensions are in
|
|
292
|
+
[Operator dashboard](dashboard.md).
|
package/docs/architecture.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
Solid Objects
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Solid Objects coordinates stateful TypeScript objects through database-backed
|
|
4
|
+
mailboxes. Each object, called an actor in the API, is addressed by
|
|
5
|
+
`(actor type, actor id)`, processes one durable turn at a time, and persists
|
|
6
|
+
JSON state between activations.
|
|
6
7
|
|
|
7
8
|
A durable message envelope selects an actor `operation` and records its
|
|
8
9
|
`delivery_mode` as `async`, `sync`, or `internal`. An operation is actor code;
|
|
@@ -59,10 +60,10 @@ than waiting for a connection or serialized SQLite slot it cannot release.
|
|
|
59
60
|
|
|
60
61
|
PostgreSQL notifications are an opt-in latency layer. One event-driven client
|
|
61
62
|
per runtime listens on role-specific channels before the worker checks durable
|
|
62
|
-
state, which closes the listener-startup race without
|
|
63
|
-
|
|
64
|
-
wakes every matching waiter. Reconnection and notification loss fall back
|
|
65
|
-
the ordinary polling interval.
|
|
63
|
+
state, which closes the listener-startup race without holding a polling
|
|
64
|
+
connection per worker. A notification advances a process-local role generation
|
|
65
|
+
and wakes every matching waiter. Reconnection and notification loss fall back
|
|
66
|
+
to the ordinary polling interval.
|
|
66
67
|
|
|
67
68
|
The optional Redis adapter provides the same role generations through Pub/Sub
|
|
68
69
|
for deployments that already operate Redis. It keeps commands and subscriptions
|
|
@@ -94,6 +95,12 @@ actor subscriptions, replays a committed observable projection, and follows
|
|
|
94
95
|
the durable broadcast outbox in revision order. The browser client applies the
|
|
95
96
|
same incarnation and revision fence without importing Node APIs.
|
|
96
97
|
|
|
98
|
+
Each observable is compared using its computed JSON value. Value-broadcast
|
|
99
|
+
observables persist that changed value in the outbox; invalidation-only
|
|
100
|
+
observables persist only the changed name. This lets a component registry
|
|
101
|
+
refresh a reauthorized view at the same dependency granularity without storing
|
|
102
|
+
or sending private projection values.
|
|
103
|
+
|
|
97
104
|
Actors may also declare static personalized payload projections. Each requested
|
|
98
105
|
name is reauthorized as a query and evaluated against a fresh actor hydrated
|
|
99
106
|
from committed state under that subscriber's session context. Payload names use
|
|
@@ -108,6 +115,5 @@ broadcast events through an application-owned shared transport and calls
|
|
|
108
115
|
another broker optional for a single Node process while making the
|
|
109
116
|
cross-process boundary explicit.
|
|
110
117
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Cloudflare's placement or edge-runtime guarantees.
|
|
118
|
+
Solid Objects provides database-backed state coordination for Node.js. It does
|
|
119
|
+
not reproduce Cloudflare's placement or edge-runtime guarantees.
|