@rool-dev/sdk 0.11.3-dev.521c0dc → 0.11.3-dev.7c57c94
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 +65 -101
- package/dist/client.d.ts +4 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -26
- package/dist/client.js.map +1 -1
- package/dist/graphql.d.ts +13 -19
- package/dist/graphql.d.ts.map +1 -1
- package/dist/graphql.js +35 -70
- package/dist/graphql.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/reroute.d.ts.map +1 -1
- package/dist/reroute.js +9 -0
- package/dist/reroute.js.map +1 -1
- package/dist/{channel.d.ts → space-session.d.ts} +44 -139
- package/dist/space-session.d.ts.map +1 -0
- package/dist/{channel.js → space-session.js} +111 -325
- package/dist/space-session.js.map +1 -0
- package/dist/space.d.ts +18 -48
- package/dist/space.d.ts.map +1 -1
- package/dist/space.js +84 -223
- package/dist/space.js.map +1 -1
- package/dist/subscription.d.ts +2 -2
- package/dist/subscription.d.ts.map +1 -1
- package/dist/subscription.js +6 -30
- package/dist/subscription.js.map +1 -1
- package/dist/types.d.ts +13 -80
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/channel.d.ts.map +0 -1
- package/dist/channel.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,9 +4,8 @@ TypeScript SDK for Rool, a persistent collaborative workspace for objects, AI-as
|
|
|
4
4
|
|
|
5
5
|
Core primitives:
|
|
6
6
|
|
|
7
|
-
- **Spaces** — containers for objects, schema, metadata,
|
|
8
|
-
- **
|
|
9
|
-
- **Conversations** — independent interaction histories within a channel.
|
|
7
|
+
- **Spaces** — containers for objects, schema, metadata, conversations, collaborators, and files.
|
|
8
|
+
- **Conversations** — independent interaction histories in a space.
|
|
10
9
|
- **Objects** — JSON records addressed by object paths such as `/space/article/welcome.json`.
|
|
11
10
|
- **Files** — user-visible files stored under `/rool-drive/...` through WebDAV.
|
|
12
11
|
|
|
@@ -31,36 +30,36 @@ async function main() {
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
const space = await client.createSpace('Solar System');
|
|
34
|
-
const
|
|
33
|
+
const conversation = space.conversation('main');
|
|
35
34
|
|
|
36
|
-
await
|
|
35
|
+
await conversation.createCollection('body', [
|
|
37
36
|
{ name: 'name', type: { kind: 'string' } },
|
|
38
37
|
{ name: 'mass', type: { kind: 'string' } },
|
|
39
38
|
{ name: 'radius', type: { kind: 'string' } },
|
|
40
39
|
{ name: 'orbits', type: { kind: 'maybe', inner: { kind: 'ref' } } },
|
|
41
40
|
]);
|
|
42
41
|
|
|
43
|
-
const { object: sun } = await
|
|
42
|
+
const { object: sun } = await conversation.putObject('/space/body/sun.json', {
|
|
44
43
|
name: 'Sun',
|
|
45
44
|
mass: '1 solar mass',
|
|
46
45
|
radius: '696,340 km',
|
|
47
46
|
});
|
|
48
47
|
|
|
49
|
-
const { object: earth } = await
|
|
48
|
+
const { object: earth } = await conversation.putObject('/space/body/earth.json', {
|
|
50
49
|
name: 'Earth',
|
|
51
50
|
mass: '1 Earth mass',
|
|
52
51
|
radius: '6,371 km',
|
|
53
52
|
orbits: sun.path,
|
|
54
53
|
});
|
|
55
54
|
|
|
56
|
-
const { message, objects } = await
|
|
55
|
+
const { message, objects } = await conversation.prompt(
|
|
57
56
|
'Add the other planets in our solar system, each referencing the Sun.'
|
|
58
57
|
);
|
|
59
58
|
|
|
60
59
|
console.log(message);
|
|
61
60
|
console.log(`Modified ${objects.length} objects`);
|
|
62
61
|
|
|
63
|
-
const loadedEarth = await
|
|
62
|
+
const loadedEarth = await space.getObject(earth.path);
|
|
64
63
|
console.log(loadedEarth?.body.name);
|
|
65
64
|
|
|
66
65
|
space.close();
|
|
@@ -230,58 +229,57 @@ that token to `client.verify(token)` once the link lands back in the app.
|
|
|
230
229
|
|
|
231
230
|
A temporarily unreachable server never reads as "logged out". `initialize()` reports authentication from stored credentials, so on an offline start it can return `true` while `currentUser` is still `null` and user storage is empty — the SDK keeps reconnecting in the background and hydrates both automatically once the server is reachable, emitting `currentUserChanged`. Only an invalid or expired refresh token ends the session, via `authStateChanged(false)`.
|
|
232
231
|
|
|
233
|
-
## Spaces and
|
|
232
|
+
## Spaces and Conversations
|
|
234
233
|
|
|
235
|
-
Open a space to receive live events and manage collaborators, file storage, and
|
|
234
|
+
Open a space to receive live events and manage collaborators, file storage, and conversations. Open a conversation to work with objects, schema, metadata, and AI.
|
|
236
235
|
|
|
237
236
|
```typescript
|
|
238
237
|
const space = await client.openSpace('space-id');
|
|
239
238
|
|
|
240
|
-
space.
|
|
239
|
+
const conversation = space.conversation('main');
|
|
241
240
|
space.on('filesChanged', () => console.log('files changed'));
|
|
242
241
|
|
|
243
|
-
|
|
244
|
-
await channel.prompt('Summarize this space');
|
|
242
|
+
await conversation.prompt('Summarize this space');
|
|
245
243
|
```
|
|
246
244
|
|
|
247
|
-
|
|
245
|
+
Conversation IDs must be 1–32 characters and contain only letters, numbers, `_`, and `-`.
|
|
248
246
|
|
|
249
247
|
## Object Operations
|
|
250
248
|
|
|
251
249
|
Objects are JSON files under `/space`. Create the collection before writing objects in it.
|
|
252
250
|
|
|
253
251
|
```typescript
|
|
254
|
-
await
|
|
252
|
+
await conversation.createCollection('article', [
|
|
255
253
|
{ name: 'title', type: { kind: 'string' } },
|
|
256
254
|
{ name: 'status', type: { kind: 'string' } },
|
|
257
255
|
]);
|
|
258
256
|
|
|
259
257
|
// Create or replace an exact object path
|
|
260
|
-
const { object } = await
|
|
258
|
+
const { object } = await conversation.putObject('/space/article/welcome.json', {
|
|
261
259
|
title: 'Welcome',
|
|
262
260
|
status: 'draft',
|
|
263
261
|
});
|
|
264
262
|
|
|
265
263
|
// Patch fields; null or undefined deletes a field
|
|
266
|
-
await
|
|
264
|
+
await conversation.patchObject(object.path, {
|
|
267
265
|
data: { status: 'published', obsoleteField: null },
|
|
268
266
|
});
|
|
269
267
|
|
|
270
268
|
// Read one or many objects
|
|
271
|
-
await
|
|
272
|
-
await
|
|
269
|
+
await space.getObject('/space/article/welcome.json');
|
|
270
|
+
await space.getObjects([
|
|
273
271
|
'/space/article/welcome.json',
|
|
274
272
|
'/space/article/intro.json',
|
|
275
273
|
]);
|
|
276
274
|
|
|
277
275
|
// Rename or move an object
|
|
278
|
-
await
|
|
276
|
+
await conversation.moveObject(
|
|
279
277
|
'/space/article/welcome.json',
|
|
280
278
|
'/space/article/hello-world.json'
|
|
281
279
|
);
|
|
282
280
|
|
|
283
281
|
// Delete objects
|
|
284
|
-
await
|
|
282
|
+
await conversation.deleteObjects(['/space/article/hello-world.json']);
|
|
285
283
|
```
|
|
286
284
|
|
|
287
285
|
| Method | Description |
|
|
@@ -299,7 +297,7 @@ await channel.deleteObjects(['/space/article/hello-world.json']);
|
|
|
299
297
|
`prompt()` invokes the AI agent. The agent can inspect space context and, unless `readOnly` or a read-only effort is used, create/modify/move/delete objects.
|
|
300
298
|
|
|
301
299
|
```typescript
|
|
302
|
-
const { message, objects } = await
|
|
300
|
+
const { message, objects } = await conversation.prompt(
|
|
303
301
|
'Create a topic node for the solar system, then child nodes for each planet.'
|
|
304
302
|
);
|
|
305
303
|
|
|
@@ -322,12 +320,12 @@ console.log(objects.map((object) => object.path));
|
|
|
322
320
|
|
|
323
321
|
```typescript
|
|
324
322
|
// Read-only quick question
|
|
325
|
-
await
|
|
323
|
+
await conversation.prompt('What topics are covered?', {
|
|
326
324
|
effort: 'QUICK', // fast/read-only
|
|
327
325
|
});
|
|
328
326
|
|
|
329
327
|
// Focus on existing objects and files
|
|
330
|
-
await
|
|
328
|
+
await conversation.prompt('Compare these resources', {
|
|
331
329
|
attachments: [
|
|
332
330
|
'/space/article/intro.json',
|
|
333
331
|
'rool-machine:/rool-drive/docs/report.pdf',
|
|
@@ -335,12 +333,12 @@ await channel.prompt('Compare these resources', {
|
|
|
335
333
|
});
|
|
336
334
|
|
|
337
335
|
// Upload a local file as an attachment
|
|
338
|
-
await
|
|
336
|
+
await conversation.prompt('Describe this image', {
|
|
339
337
|
attachments: [fileInput.files![0]],
|
|
340
338
|
});
|
|
341
339
|
|
|
342
340
|
// Structured response
|
|
343
|
-
const { message } = await
|
|
341
|
+
const { message } = await conversation.prompt('Categorize these items', {
|
|
344
342
|
responseSchema: {
|
|
345
343
|
type: 'object',
|
|
346
344
|
properties: {
|
|
@@ -353,7 +351,7 @@ const result = JSON.parse(message);
|
|
|
353
351
|
|
|
354
352
|
// Stop a long prompt with a signal (when the caller holds the controller)
|
|
355
353
|
const ac = new AbortController();
|
|
356
|
-
const promptPromise =
|
|
354
|
+
const promptPromise = conversation.prompt('Do a deep analysis', {
|
|
357
355
|
effort: 'RESEARCH',
|
|
358
356
|
signal: ac.signal,
|
|
359
357
|
});
|
|
@@ -365,39 +363,33 @@ await promptPromise;
|
|
|
365
363
|
|
|
366
364
|
Use `signal` when the same call site cancels the prompt. When the Stop button
|
|
367
365
|
lives elsewhere — a different component, after a reload, or a prompt another
|
|
368
|
-
client started — stop by ID or
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
billed.
|
|
366
|
+
client started — stop by interaction ID or through a conversation handle. Both
|
|
367
|
+
are best-effort: the server halts the agent loop and closes the stream, but an
|
|
368
|
+
LLM turn already in flight keeps generating server-side and is billed.
|
|
372
369
|
|
|
373
370
|
```typescript
|
|
374
|
-
// Stop
|
|
375
|
-
//
|
|
376
|
-
await
|
|
377
|
-
|
|
378
|
-
// Stop a specific interaction by ID (e.g. from channel.activeLeafId or
|
|
379
|
-
// the interactions list). Returns whether the server stopped it.
|
|
380
|
-
await channel.stopInteraction(channel.activeLeafId!);
|
|
371
|
+
// Stop a specific interaction by ID (for example, from conversation.activeLeafId
|
|
372
|
+
// or the interactions list). Returns whether the server stopped it.
|
|
373
|
+
await space.stopInteraction(conversation.activeLeafId!);
|
|
381
374
|
|
|
382
375
|
// Conversation handles stop their own in-flight interaction.
|
|
383
|
-
const thread =
|
|
376
|
+
const thread = space.conversation('thread-42');
|
|
384
377
|
await thread.stop();
|
|
385
378
|
```
|
|
386
379
|
|
|
387
380
|
| Method | Description |
|
|
388
381
|
| --- | --- |
|
|
389
|
-
| `stop(): Promise<boolean>` | Stop the in-flight interaction on the default conversation; `false` if none. |
|
|
390
382
|
| `stopInteraction(id): Promise<boolean>` | Ask the server to stop a specific interaction by ID. |
|
|
391
383
|
| `conversation.stop(): Promise<boolean>` | Stop a specific conversation's in-flight interaction. |
|
|
392
384
|
|
|
393
385
|
## Conversations
|
|
394
386
|
|
|
395
|
-
|
|
387
|
+
Use `space.conversation(id)` for independent histories (for example, multiple chat threads). Conversations are represented as trees: interactions point at a `parentId`, and the SDK tracks an active leaf for each conversation.
|
|
396
388
|
|
|
397
389
|
```typescript
|
|
398
|
-
await
|
|
390
|
+
await conversation.prompt('Hello');
|
|
399
391
|
|
|
400
|
-
const thread =
|
|
392
|
+
const thread = space.conversation('thread-42');
|
|
401
393
|
await thread.prompt('Hello from another thread');
|
|
402
394
|
await thread.setSystemInstruction('Answer in haiku');
|
|
403
395
|
|
|
@@ -411,15 +403,14 @@ if (thread.activeLeafId) {
|
|
|
411
403
|
|
|
412
404
|
| Method/property | Description |
|
|
413
405
|
| --- | --- |
|
|
414
|
-
| `
|
|
406
|
+
| `space.conversation(id): ConversationHandle` | Get a conversation-scoped handle. |
|
|
415
407
|
| `getInteractions(): Interaction[]` | Active branch as a flat list. |
|
|
416
408
|
| `getTree(): Record<string, Interaction>` | Full interaction tree. |
|
|
417
409
|
| `activeLeafId` | Current branch tip. |
|
|
418
410
|
| `setActiveLeaf(id): void` | Switch branches. |
|
|
419
411
|
| `getSystemInstruction()` / `setSystemInstruction(value)` | Manage conversation system instruction. Pass `null` to clear. |
|
|
420
|
-
| `getConversations(): ConversationInfo[]` | List
|
|
412
|
+
| `getConversations(): ConversationInfo[]` | List conversations in the space. |
|
|
421
413
|
| `deleteConversation(id): Promise<void>` | Delete a non-active conversation. |
|
|
422
|
-
| `renameConversation(name): Promise<void>` | Rename the current/default conversation (on `RoolChannel`). |
|
|
423
414
|
| `conversation.rename(name): Promise<void>` | Rename a specific conversation handle. |
|
|
424
415
|
|
|
425
416
|
`ConversationHandle` also supports conversation-scoped `putObject`, `patchObject`, `moveObject`, `deleteObjects`, `prompt`, `stop`, collection-schema methods, and `setMetadata`.
|
|
@@ -429,7 +420,7 @@ if (thread.activeLeafId) {
|
|
|
429
420
|
Collections define the schema visible to the AI agent. Hidden body fields whose names start with `_` are useful for app/UI state that should not be considered by AI.
|
|
430
421
|
|
|
431
422
|
```typescript
|
|
432
|
-
await
|
|
423
|
+
await conversation.createCollection('article', {
|
|
433
424
|
schemaOrgType: 'Article',
|
|
434
425
|
fields: [
|
|
435
426
|
{ name: 'title', type: { kind: 'string' } },
|
|
@@ -439,15 +430,15 @@ await channel.createCollection('article', {
|
|
|
439
430
|
],
|
|
440
431
|
});
|
|
441
432
|
|
|
442
|
-
const schema =
|
|
433
|
+
const schema = space.getSchema();
|
|
443
434
|
|
|
444
|
-
await
|
|
435
|
+
await conversation.alterCollection('article', [
|
|
445
436
|
{ name: 'title', type: { kind: 'string' } },
|
|
446
437
|
{ name: 'status', type: { kind: 'string' } },
|
|
447
438
|
]);
|
|
448
439
|
|
|
449
|
-
|
|
450
|
-
const viewport =
|
|
440
|
+
conversation.setMetadata('viewport', { x: 0, y: 0, zoom: 1 });
|
|
441
|
+
const viewport = space.getMetadata('viewport');
|
|
451
442
|
```
|
|
452
443
|
|
|
453
444
|
| Method | Description |
|
|
@@ -464,14 +455,14 @@ Field kinds: `string`, `number`, `boolean`, `ref`, `enum`, `literal`, `array`, a
|
|
|
464
455
|
|
|
465
456
|
## Undo/Redo
|
|
466
457
|
|
|
467
|
-
Undo/redo uses checkpoints
|
|
458
|
+
Undo/redo uses checkpoints over the whole space. A checkpoint captures space state; call `checkpoint()` before a user action you want to make undoable.
|
|
468
459
|
|
|
469
460
|
```typescript
|
|
470
|
-
await
|
|
471
|
-
await
|
|
461
|
+
await space.checkpoint('Delete article');
|
|
462
|
+
await conversation.deleteObjects(['/space/article/welcome.json']);
|
|
472
463
|
|
|
473
|
-
if (await
|
|
474
|
-
await
|
|
464
|
+
if (await space.canUndo()) {
|
|
465
|
+
await space.undo();
|
|
475
466
|
}
|
|
476
467
|
```
|
|
477
468
|
|
|
@@ -484,7 +475,7 @@ if (await channel.canUndo()) {
|
|
|
484
475
|
| `redo(): Promise<boolean>` | Reapply undone work. |
|
|
485
476
|
| `clearHistory(): Promise<void>` | Clear checkpoint history. |
|
|
486
477
|
|
|
487
|
-
Undo/redo availability and history are scoped to the
|
|
478
|
+
Undo/redo availability and history are scoped to the space.
|
|
488
479
|
|
|
489
480
|
## File Storage and WebDAV
|
|
490
481
|
|
|
@@ -650,7 +641,7 @@ const client = new RoolClient({
|
|
|
650
641
|
| `getAllUserStorage(): Record<string, unknown>` | Copy all cached user storage. |
|
|
651
642
|
| `reportEvent(event, url?): void` | Fire-and-forget telemetry event. |
|
|
652
643
|
| `destroy(): void` | Close subscriptions, spaces, auth resources, and listeners. |
|
|
653
|
-
| `generateId(): string` | Generate a
|
|
644
|
+
| `generateId(): string` | Generate a unique ID suitable for conversation IDs. |
|
|
654
645
|
|
|
655
646
|
### Client events
|
|
656
647
|
|
|
@@ -660,9 +651,6 @@ client.on('currentUserChanged', (user) => void 0); // CurrentUser | null; null o
|
|
|
660
651
|
client.on('spaceAdded', (space) => void 0);
|
|
661
652
|
client.on('spaceRemoved', (spaceId) => void 0);
|
|
662
653
|
client.on('spaceRenamed', (spaceId, newName) => void 0);
|
|
663
|
-
client.on('channelCreated', (spaceId, channel) => void 0);
|
|
664
|
-
client.on('channelUpdated', (spaceId, channel) => void 0);
|
|
665
|
-
client.on('channelDeleted', (spaceId, channelId) => void 0);
|
|
666
654
|
client.on('userStorageChanged', ({ key, value, source }) => void 0);
|
|
667
655
|
client.on('connectionStateChanged', (state) => void 0);
|
|
668
656
|
client.on('error', (error, context) => void 0);
|
|
@@ -670,12 +658,18 @@ client.on('error', (error, context) => void 0);
|
|
|
670
658
|
|
|
671
659
|
## RoolSpace API
|
|
672
660
|
|
|
673
|
-
Properties: `id`, `name`, `role`, `memberCount`, `
|
|
661
|
+
Properties: `id`, `name`, `role`, `memberCount`, `conversations`, `route`, `webdav`.
|
|
674
662
|
|
|
675
663
|
| Method | Description |
|
|
676
664
|
| --- | --- |
|
|
677
|
-
| `
|
|
678
|
-
| `
|
|
665
|
+
| `conversation(conversationId): ConversationHandle` | Get a conversation-scoped handle. |
|
|
666
|
+
| `getObject`, `getObjects`, `stat` | Read object data and stats. |
|
|
667
|
+
| `getConversations`, `deleteConversation` | List and delete conversations. |
|
|
668
|
+
| `getMetadata`, `getAllMetadata`, `getSchema` | Read metadata and schema. |
|
|
669
|
+
| `checkpoint`, `canUndo`, `canRedo`, `undo`, `redo`, `clearHistory` | Space history controls. |
|
|
670
|
+
| `stopInteraction(interactionId): Promise<boolean>` | Stop an in-flight interaction by ID. |
|
|
671
|
+
| `fetch(url, init?): Promise<Response>` | Proxy an external HTTP request through the server to bypass browser CORS. |
|
|
672
|
+
| `close(): void` | Stop the space subscription. |
|
|
679
673
|
| `rename(newName): Promise<void>` | Rename the space. |
|
|
680
674
|
| `delete(): Promise<void>` | Permanently delete the space. |
|
|
681
675
|
| `listUsers(): Promise<SpaceMember[]>` | List collaborators. |
|
|
@@ -684,8 +678,6 @@ Properties: `id`, `name`, `role`, `memberCount`, `channels`, `route`, `webdav`.
|
|
|
684
678
|
| `createInvite(role, options?): Promise<SpaceInviteCreated>` | Mint an invite link; `options` takes `email`, `expiresInDays`, `maxUses`. |
|
|
685
679
|
| `listInvites(): Promise<SpaceInvite[]>` | List currently redeemable invites. |
|
|
686
680
|
| `revokeInvite(inviteId): Promise<boolean>` | Revoke an invite so its link stops working. |
|
|
687
|
-
| `renameChannel(channelId, name): Promise<void>` | Rename a channel. |
|
|
688
|
-
| `deleteChannel(channelId): Promise<void>` | Delete a channel and history. |
|
|
689
681
|
| `exportArchive(): Promise<Blob>` | Export a space archive. |
|
|
690
682
|
| `refresh(): Promise<void>` | Refresh cached space data. |
|
|
691
683
|
| `fetchPath(path, options?): Promise<Response>` | Fetch a `/rool-drive/...` file. |
|
|
@@ -694,42 +686,15 @@ Properties: `id`, `name`, `role`, `memberCount`, `channels`, `route`, `webdav`.
|
|
|
694
686
|
Events:
|
|
695
687
|
|
|
696
688
|
```typescript
|
|
697
|
-
space.on('
|
|
698
|
-
space.on('
|
|
699
|
-
space.on('
|
|
689
|
+
space.on('metadataUpdated', ({ metadata, source }) => void 0);
|
|
690
|
+
space.on('schemaUpdated', ({ schema, source }) => void 0);
|
|
691
|
+
space.on('conversationUpdated', ({ conversationId, source }) => void 0);
|
|
692
|
+
space.on('reset', ({ source }) => void 0);
|
|
693
|
+
space.on('syncError', (error) => void 0);
|
|
700
694
|
space.on('filesChanged', ({ spaceId, source, timestamp }) => void 0);
|
|
701
695
|
space.on('filesReset', ({ spaceId, source, timestamp }) => void 0);
|
|
702
696
|
space.on('connectionStateChanged', (state) => void 0);
|
|
703
697
|
```
|
|
704
|
-
|
|
705
|
-
## RoolChannel API
|
|
706
|
-
|
|
707
|
-
Properties: `id` (space ID), `name` (space name), `role`, `userId`, `channelId`, `channelName`, `conversationId`, `isReadOnly`, `activeLeafId`.
|
|
708
|
-
|
|
709
|
-
| Area | Methods |
|
|
710
|
-
| --- | --- |
|
|
711
|
-
| Lifecycle | `close()`, `rename(name)`, `conversation(id)` |
|
|
712
|
-
| Objects | `getObject`, `getObjects`, `stat`, `putObject`, `patchObject`, `moveObject`, `deleteObjects` |
|
|
713
|
-
| Schema | `getSchema`, `createCollection`, `alterCollection`, `dropCollection` |
|
|
714
|
-
| Metadata | `setMetadata`, `getMetadata`, `getAllMetadata` |
|
|
715
|
-
| Conversations | `getInteractions`, `getTree`, `setActiveLeaf`, `getConversations`, `deleteConversation`, `getSystemInstruction`, `setSystemInstruction`, `renameConversation` |
|
|
716
|
-
| AI | `prompt`, `stop`, `stopInteraction` |
|
|
717
|
-
| Undo/redo | `checkpoint`, `canUndo`, `canRedo`, `undo`, `redo`, `clearHistory` |
|
|
718
|
-
| Utilities | `fetch(url, init?)` server-side proxied fetch |
|
|
719
|
-
|
|
720
|
-
Channel events:
|
|
721
|
-
|
|
722
|
-
```typescript
|
|
723
|
-
channel.on('metadataUpdated', ({ metadata, source }) => void 0);
|
|
724
|
-
channel.on('schemaUpdated', ({ schema, source }) => void 0);
|
|
725
|
-
channel.on('channelUpdated', ({ channelId, source }) => void 0);
|
|
726
|
-
channel.on('conversationUpdated', ({ conversationId, channelId, source }) => void 0);
|
|
727
|
-
channel.on('reset', ({ source }) => void 0);
|
|
728
|
-
channel.on('syncError', (error) => void 0);
|
|
729
|
-
```
|
|
730
|
-
|
|
731
|
-
`channel.fetch(url, init?)` proxies external HTTP requests through the server to bypass browser CORS.
|
|
732
|
-
|
|
733
698
|
## Import/Export
|
|
734
699
|
|
|
735
700
|
```typescript
|
|
@@ -737,7 +702,7 @@ const archive = await space.exportArchive();
|
|
|
737
702
|
const imported = await client.importArchive('Imported Data', archive);
|
|
738
703
|
```
|
|
739
704
|
|
|
740
|
-
Archives include objects, metadata,
|
|
705
|
+
Archives include objects, metadata, conversations, and file storage.
|
|
741
706
|
|
|
742
707
|
## Data Types
|
|
743
708
|
|
|
@@ -839,7 +804,6 @@ interface RoolObjectStat {
|
|
|
839
804
|
modifiedAt: number;
|
|
840
805
|
modifiedBy: string;
|
|
841
806
|
modifiedByName: string | null;
|
|
842
|
-
modifiedInChannel: string;
|
|
843
807
|
modifiedInConversation: string | null;
|
|
844
808
|
modifiedInInteraction: string | null;
|
|
845
809
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -4,12 +4,11 @@ import type { RoolClientConfig, RoolClientEvents, RoolSpaceInfo, CurrentUser, In
|
|
|
4
4
|
/**
|
|
5
5
|
* Rool Client - Manages authentication, space lifecycle, and shared infrastructure.
|
|
6
6
|
*
|
|
7
|
-
* The client is lightweight - most operations happen on RoolSpace
|
|
7
|
+
* The client is lightweight - most operations happen on RoolSpace instances.
|
|
8
8
|
*
|
|
9
9
|
* Features:
|
|
10
10
|
* - Authentication (login, logout, token management)
|
|
11
11
|
* - Space lifecycle (list, create, delete, rename)
|
|
12
|
-
* - Channel management (open, list, rename, delete)
|
|
13
12
|
* - Client-level subscription for lifecycle events
|
|
14
13
|
* - User storage (cross-device key-value storage)
|
|
15
14
|
*/
|
|
@@ -137,7 +136,7 @@ export declare class RoolClient extends EventEmitter<RoolClientEvents> {
|
|
|
137
136
|
listSpaces(): Promise<RoolSpaceInfo[]>;
|
|
138
137
|
/**
|
|
139
138
|
* Open a space with a real-time subscription.
|
|
140
|
-
* Returns a live RoolSpace handle with
|
|
139
|
+
* Returns a live RoolSpace handle with conversation and file events.
|
|
141
140
|
* Reuses an existing handle if the space is already open.
|
|
142
141
|
*
|
|
143
142
|
* Call space.close() when done to stop the subscription.
|
|
@@ -146,12 +145,12 @@ export declare class RoolClient extends EventEmitter<RoolClientEvents> {
|
|
|
146
145
|
/**
|
|
147
146
|
* Create a new space.
|
|
148
147
|
* Returns a RoolSpace handle with a real-time subscription.
|
|
149
|
-
*
|
|
148
|
+
* Use the returned RoolSpace to work with objects, conversations, and AI.
|
|
150
149
|
*/
|
|
151
150
|
createSpace(name: string): Promise<RoolSpace>;
|
|
152
151
|
/**
|
|
153
152
|
* Delete a space.
|
|
154
|
-
* Note: This
|
|
153
|
+
* Note: This closes any cached open RoolSpace handle.
|
|
155
154
|
*/
|
|
156
155
|
deleteSpace(spaceId: string): Promise<void>;
|
|
157
156
|
/**
|
|
@@ -238,8 +237,6 @@ export declare class RoolClient extends EventEmitter<RoolClientEvents> {
|
|
|
238
237
|
_graphql<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
|
|
239
238
|
/**
|
|
240
239
|
* Handle a client-level event from the subscription.
|
|
241
|
-
* Channel events from the client SSE are ignored — they're handled by
|
|
242
|
-
* the space subscription via RoolSpace instead.
|
|
243
240
|
* @internal
|
|
244
241
|
*/
|
|
245
242
|
private handleClientEvent;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -3,19 +3,26 @@ import { AuthManager } from './auth.js';
|
|
|
3
3
|
import { GraphQLClient } from './graphql.js';
|
|
4
4
|
import { ClientSubscriptionManager } from './subscription.js';
|
|
5
5
|
import { RestClient } from './rest.js';
|
|
6
|
-
import { generateEntityId } from './channel.js';
|
|
7
6
|
import { RoolSpace } from './space.js';
|
|
8
7
|
import { SpaceRouter } from './router.js';
|
|
9
8
|
import { defaultLogger } from './logger.js';
|
|
9
|
+
function generateEntityId() {
|
|
10
|
+
const alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
|
|
11
|
+
const bytes = new Uint8Array(16);
|
|
12
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
13
|
+
let id = '';
|
|
14
|
+
for (let i = 0; i < 16; i++)
|
|
15
|
+
id += alphabet[bytes[i] & 63];
|
|
16
|
+
return id;
|
|
17
|
+
}
|
|
10
18
|
/**
|
|
11
19
|
* Rool Client - Manages authentication, space lifecycle, and shared infrastructure.
|
|
12
20
|
*
|
|
13
|
-
* The client is lightweight - most operations happen on RoolSpace
|
|
21
|
+
* The client is lightweight - most operations happen on RoolSpace instances.
|
|
14
22
|
*
|
|
15
23
|
* Features:
|
|
16
24
|
* - Authentication (login, logout, token management)
|
|
17
25
|
* - Space lifecycle (list, create, delete, rename)
|
|
18
|
-
* - Channel management (open, list, rename, delete)
|
|
19
26
|
* - Client-level subscription for lifecycle events
|
|
20
27
|
* - User storage (cross-device key-value storage)
|
|
21
28
|
*/
|
|
@@ -27,7 +34,7 @@ export class RoolClient extends EventEmitter {
|
|
|
27
34
|
router;
|
|
28
35
|
subscriptionManager = null;
|
|
29
36
|
logger;
|
|
30
|
-
// Open spaces (cached for reuse
|
|
37
|
+
// Open spaces (cached for reuse)
|
|
31
38
|
openSpaces = new Map();
|
|
32
39
|
// User storage cache (in-memory; populated from server on initialize)
|
|
33
40
|
_storageCache = {};
|
|
@@ -134,7 +141,7 @@ export class RoolClient extends EventEmitter {
|
|
|
134
141
|
destroy() {
|
|
135
142
|
this.authManager.destroy();
|
|
136
143
|
this.subscriptionManager?.destroy();
|
|
137
|
-
// Close all open spaces
|
|
144
|
+
// Close all open spaces and subscriptions
|
|
138
145
|
for (const space of this.openSpaces.values())
|
|
139
146
|
space.close();
|
|
140
147
|
this.openSpaces.clear();
|
|
@@ -222,7 +229,7 @@ export class RoolClient extends EventEmitter {
|
|
|
222
229
|
logout() {
|
|
223
230
|
this.authManager.logout();
|
|
224
231
|
this.unsubscribe();
|
|
225
|
-
// Close all open spaces
|
|
232
|
+
// Close all open spaces and subscriptions
|
|
226
233
|
for (const space of this.openSpaces.values())
|
|
227
234
|
space.close();
|
|
228
235
|
this.openSpaces.clear();
|
|
@@ -271,7 +278,7 @@ export class RoolClient extends EventEmitter {
|
|
|
271
278
|
}
|
|
272
279
|
/**
|
|
273
280
|
* Open a space with a real-time subscription.
|
|
274
|
-
* Returns a live RoolSpace handle with
|
|
281
|
+
* Returns a live RoolSpace handle with conversation and file events.
|
|
275
282
|
* Reuses an existing handle if the space is already open.
|
|
276
283
|
*
|
|
277
284
|
* Call space.close() when done to stop the subscription.
|
|
@@ -311,22 +318,12 @@ export class RoolClient extends EventEmitter {
|
|
|
311
318
|
onClose: () => this.openSpaces.delete(spaceId),
|
|
312
319
|
});
|
|
313
320
|
this.openSpaces.set(spaceId, space);
|
|
314
|
-
// Forward space channel events to client-level events (backwards compat)
|
|
315
|
-
space.on('channelCreated', (channel) => {
|
|
316
|
-
this.emit('channelCreated', spaceId, channel);
|
|
317
|
-
});
|
|
318
|
-
space.on('channelUpdated', (channel) => {
|
|
319
|
-
this.emit('channelUpdated', spaceId, channel);
|
|
320
|
-
});
|
|
321
|
-
space.on('channelDeleted', (channelId) => {
|
|
322
|
-
this.emit('channelDeleted', spaceId, channelId);
|
|
323
|
-
});
|
|
324
321
|
return space;
|
|
325
322
|
}
|
|
326
323
|
/**
|
|
327
324
|
* Create a new space.
|
|
328
325
|
* Returns a RoolSpace handle with a real-time subscription.
|
|
329
|
-
*
|
|
326
|
+
* Use the returned RoolSpace to work with objects, conversations, and AI.
|
|
330
327
|
*/
|
|
331
328
|
async createSpace(name) {
|
|
332
329
|
// Prevents a rejection here from crashing Node before the caller awaits it.
|
|
@@ -336,7 +333,7 @@ export class RoolClient extends EventEmitter {
|
|
|
336
333
|
}
|
|
337
334
|
/**
|
|
338
335
|
* Delete a space.
|
|
339
|
-
* Note: This
|
|
336
|
+
* Note: This closes any cached open RoolSpace handle.
|
|
340
337
|
*/
|
|
341
338
|
async deleteSpace(spaceId) {
|
|
342
339
|
await this.graphqlClient.deleteSpace(spaceId);
|
|
@@ -521,8 +518,6 @@ export class RoolClient extends EventEmitter {
|
|
|
521
518
|
}
|
|
522
519
|
/**
|
|
523
520
|
* Handle a client-level event from the subscription.
|
|
524
|
-
* Channel events from the client SSE are ignored — they're handled by
|
|
525
|
-
* the space subscription via RoolSpace instead.
|
|
526
521
|
* @internal
|
|
527
522
|
*/
|
|
528
523
|
handleClientEvent(event) {
|
|
@@ -567,11 +562,6 @@ export class RoolClient extends EventEmitter {
|
|
|
567
562
|
case 'user_storage_changed':
|
|
568
563
|
this.handleUserStorageChanged(event.key, event.value);
|
|
569
564
|
break;
|
|
570
|
-
// Channel events from client SSE are ignored — handled by RoolSpace
|
|
571
|
-
case 'channel_created':
|
|
572
|
-
case 'channel_renamed':
|
|
573
|
-
case 'channel_deleted':
|
|
574
|
-
break;
|
|
575
565
|
}
|
|
576
566
|
}
|
|
577
567
|
/**
|