@rool-dev/svelte 0.1.11 → 0.1.12
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 +49 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/space.svelte.d.ts +49 -8
- package/dist/space.svelte.d.ts.map +1 -1
- package/dist/space.svelte.js +103 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,6 +50,8 @@ The Svelte wrapper adds reactive state on top of the SDK:
|
|
|
50
50
|
| `rool.spacesError` | Error from loading spaces |
|
|
51
51
|
| `rool.connectionState` | SSE connection state |
|
|
52
52
|
| `space.interactions` | Conversation interactions (auto-updates) |
|
|
53
|
+
| `collection.objects` | Objects matching a filter (auto-updates) |
|
|
54
|
+
| `collection.loading` | Whether collection is loading |
|
|
53
55
|
|
|
54
56
|
Everything else passes through to the SDK directly. See the [SDK documentation](../sdk/README.md) for full API details.
|
|
55
57
|
|
|
@@ -130,6 +132,52 @@ space.close();
|
|
|
130
132
|
{/if}
|
|
131
133
|
```
|
|
132
134
|
|
|
135
|
+
### Reactive Collections
|
|
136
|
+
|
|
137
|
+
Create auto-updating collections of objects filtered by field values:
|
|
138
|
+
|
|
139
|
+
```svelte
|
|
140
|
+
<script>
|
|
141
|
+
let space = $state(null);
|
|
142
|
+
let articles = $state(null);
|
|
143
|
+
|
|
144
|
+
async function open(id) {
|
|
145
|
+
space = await rool.openSpace(id);
|
|
146
|
+
// Create a reactive collection of all objects where type === 'article'
|
|
147
|
+
articles = space.collection({ where: { type: 'article' } });
|
|
148
|
+
}
|
|
149
|
+
</script>
|
|
150
|
+
|
|
151
|
+
{#if articles}
|
|
152
|
+
{#if articles.loading}
|
|
153
|
+
<p>Loading...</p>
|
|
154
|
+
{:else}
|
|
155
|
+
{#each articles.objects as article}
|
|
156
|
+
<div>{article.title}</div>
|
|
157
|
+
{/each}
|
|
158
|
+
{/if}
|
|
159
|
+
{/if}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Collections automatically re-fetch when objects matching the filter are created, updated, or deleted. Since the SDK caches objects locally, re-fetches are typically instant (no network round-trip).
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Collection options (same as findObjects, but no AI prompt)
|
|
166
|
+
const articles = space.collection({
|
|
167
|
+
where: { type: 'article', status: 'published' },
|
|
168
|
+
order: 'desc', // by modifiedAt (default)
|
|
169
|
+
limit: 20,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Reactive state
|
|
173
|
+
articles.objects // $state<RoolObject[]>
|
|
174
|
+
articles.loading // $state<boolean>
|
|
175
|
+
|
|
176
|
+
// Methods
|
|
177
|
+
articles.refresh() // Manual re-fetch
|
|
178
|
+
articles.close() // Stop listening for updates
|
|
179
|
+
```
|
|
180
|
+
|
|
133
181
|
### Using the SDK
|
|
134
182
|
|
|
135
183
|
All `RoolSpace` methods and properties are available on `ReactiveSpace`:
|
|
@@ -183,7 +231,7 @@ const id = generateId();
|
|
|
183
231
|
|
|
184
232
|
```typescript
|
|
185
233
|
// Package types
|
|
186
|
-
import type { Rool, ReactiveSpace } from '@rool-dev/svelte';
|
|
234
|
+
import type { Rool, ReactiveSpace, ReactiveCollection, CollectionOptions } from '@rool-dev/svelte';
|
|
187
235
|
|
|
188
236
|
// Re-exported from @rool-dev/sdk
|
|
189
237
|
import type {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createRool, generateId } from './rool.svelte.js';
|
|
2
2
|
export { wrapSpace } from './space.svelte.js';
|
|
3
3
|
export type { Rool } from './rool.svelte.js';
|
|
4
|
-
export type { ReactiveSpace } from './space.svelte.js';
|
|
4
|
+
export type { ReactiveSpace, ReactiveCollection, CollectionOptions } from './space.svelte.js';
|
|
5
5
|
export type { RoolClientConfig, RoolSpace, RoolSpaceInfo, RoolObject, RoolUserRole, ConnectionState, ConversationInfo, CurrentUser, Interaction, FindObjectsOptions, PromptOptions, CreateObjectOptions, UpdateObjectOptions, } from '@rool-dev/sdk';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG9F,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,eAAe,CAAC"}
|
package/dist/space.svelte.d.ts
CHANGED
|
@@ -1,4 +1,34 @@
|
|
|
1
|
-
import type { RoolSpace, Interaction } from '@rool-dev/sdk';
|
|
1
|
+
import type { RoolSpace, Interaction, RoolObject } from '@rool-dev/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Options for creating a reactive collection.
|
|
4
|
+
* Same as FindObjectsOptions but without `prompt` (AI queries are too slow for reactive updates).
|
|
5
|
+
*/
|
|
6
|
+
export interface CollectionOptions {
|
|
7
|
+
/** Field requirements for exact matching */
|
|
8
|
+
where?: Record<string, unknown>;
|
|
9
|
+
/** Maximum number of objects */
|
|
10
|
+
limit?: number;
|
|
11
|
+
/** Sort order by modifiedAt: 'asc' or 'desc' (default: 'desc') */
|
|
12
|
+
order?: 'asc' | 'desc';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A reactive collection of objects that auto-updates when matching objects change.
|
|
16
|
+
*/
|
|
17
|
+
declare class ReactiveCollectionImpl {
|
|
18
|
+
#private;
|
|
19
|
+
objects: RoolObject[];
|
|
20
|
+
loading: boolean;
|
|
21
|
+
constructor(space: RoolSpace, options: CollectionOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Re-fetch the collection from the space.
|
|
24
|
+
*/
|
|
25
|
+
refresh(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Stop listening for updates and clean up.
|
|
28
|
+
*/
|
|
29
|
+
close(): void;
|
|
30
|
+
}
|
|
31
|
+
export type ReactiveCollection = ReactiveCollectionImpl;
|
|
2
32
|
/**
|
|
3
33
|
* Minimal wrapper that adds reactive `interactions` to RoolSpace.
|
|
4
34
|
* All other properties and methods are proxied to the underlying space.
|
|
@@ -14,29 +44,29 @@ declare class ReactiveSpaceImpl {
|
|
|
14
44
|
get conversationId(): string;
|
|
15
45
|
set conversationId(id: string);
|
|
16
46
|
close(): void;
|
|
17
|
-
getObject(...args: Parameters<RoolSpace['getObject']>): Promise<
|
|
47
|
+
getObject(...args: Parameters<RoolSpace['getObject']>): Promise<RoolObject | undefined>;
|
|
18
48
|
stat(...args: Parameters<RoolSpace['stat']>): Promise<import("@rool-dev/sdk").RoolObjectStat | undefined>;
|
|
19
49
|
findObjects(...args: Parameters<RoolSpace['findObjects']>): Promise<{
|
|
20
|
-
objects:
|
|
50
|
+
objects: RoolObject[];
|
|
21
51
|
message: string;
|
|
22
52
|
}>;
|
|
23
53
|
getObjectIds(...args: Parameters<RoolSpace['getObjectIds']>): string[];
|
|
24
54
|
createObject(...args: Parameters<RoolSpace['createObject']>): Promise<{
|
|
25
|
-
object:
|
|
55
|
+
object: RoolObject;
|
|
26
56
|
message: string;
|
|
27
57
|
}>;
|
|
28
58
|
updateObject(...args: Parameters<RoolSpace['updateObject']>): Promise<{
|
|
29
|
-
object:
|
|
59
|
+
object: RoolObject;
|
|
30
60
|
message: string;
|
|
31
61
|
}>;
|
|
32
62
|
deleteObjects(...args: Parameters<RoolSpace['deleteObjects']>): Promise<void>;
|
|
33
63
|
link(...args: Parameters<RoolSpace['link']>): Promise<void>;
|
|
34
64
|
unlink(...args: Parameters<RoolSpace['unlink']>): Promise<boolean>;
|
|
35
|
-
getParents(...args: Parameters<RoolSpace['getParents']>): Promise<
|
|
36
|
-
getChildren(...args: Parameters<RoolSpace['getChildren']>): Promise<
|
|
65
|
+
getParents(...args: Parameters<RoolSpace['getParents']>): Promise<RoolObject[]>;
|
|
66
|
+
getChildren(...args: Parameters<RoolSpace['getChildren']>): Promise<RoolObject[]>;
|
|
37
67
|
prompt(...args: Parameters<RoolSpace['prompt']>): Promise<{
|
|
38
68
|
message: string;
|
|
39
|
-
objects:
|
|
69
|
+
objects: RoolObject[];
|
|
40
70
|
}>;
|
|
41
71
|
checkpoint(...args: Parameters<RoolSpace['checkpoint']>): Promise<string>;
|
|
42
72
|
canUndo(): Promise<boolean>;
|
|
@@ -62,6 +92,17 @@ declare class ReactiveSpaceImpl {
|
|
|
62
92
|
exportArchive(): Promise<Blob>;
|
|
63
93
|
on(...args: Parameters<RoolSpace['on']>): () => void;
|
|
64
94
|
off(...args: Parameters<RoolSpace['off']>): void;
|
|
95
|
+
/**
|
|
96
|
+
* Create a reactive collection that auto-updates when matching objects change.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* const articles = space.collection({ where: { type: 'article' } });
|
|
100
|
+
* // articles.objects is reactive
|
|
101
|
+
* // articles.loading indicates fetch status
|
|
102
|
+
* // articles.refresh() to manually re-fetch
|
|
103
|
+
* // articles.close() to stop listening
|
|
104
|
+
*/
|
|
105
|
+
collection(options: CollectionOptions): ReactiveCollection;
|
|
65
106
|
rename(...args: Parameters<RoolSpace['rename']>): Promise<void>;
|
|
66
107
|
getData(): import("@rool-dev/sdk").RoolSpaceData;
|
|
67
108
|
get isReadOnly(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"space.svelte.d.ts","sourceRoot":"","sources":["../src/space.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"space.svelte.d.ts","sourceRoot":"","sources":["../src/space.svelte.ts"],"names":[],"mappings":"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"}
|
package/dist/space.svelte.js
CHANGED
|
@@ -1,3 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A reactive collection of objects that auto-updates when matching objects change.
|
|
3
|
+
*/
|
|
4
|
+
class ReactiveCollectionImpl {
|
|
5
|
+
#space;
|
|
6
|
+
#options;
|
|
7
|
+
#unsubscribers = [];
|
|
8
|
+
#currentIds = new Set();
|
|
9
|
+
// Reactive state
|
|
10
|
+
objects = $state([]);
|
|
11
|
+
loading = $state(true);
|
|
12
|
+
constructor(space, options) {
|
|
13
|
+
this.#space = space;
|
|
14
|
+
this.#options = options;
|
|
15
|
+
this.#setup();
|
|
16
|
+
}
|
|
17
|
+
#setup() {
|
|
18
|
+
// Initial fetch
|
|
19
|
+
this.refresh();
|
|
20
|
+
// Subscribe to object events
|
|
21
|
+
const onObjectCreated = ({ object }) => {
|
|
22
|
+
if (this.#matches(object)) {
|
|
23
|
+
this.refresh();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
this.#space.on('objectCreated', onObjectCreated);
|
|
27
|
+
this.#unsubscribers.push(() => this.#space.off('objectCreated', onObjectCreated));
|
|
28
|
+
const onObjectUpdated = ({ objectId, object }) => {
|
|
29
|
+
// Re-fetch if object was in collection OR now matches the filter
|
|
30
|
+
if (this.#currentIds.has(objectId) || this.#matches(object)) {
|
|
31
|
+
this.refresh();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
this.#space.on('objectUpdated', onObjectUpdated);
|
|
35
|
+
this.#unsubscribers.push(() => this.#space.off('objectUpdated', onObjectUpdated));
|
|
36
|
+
const onObjectDeleted = ({ objectId }) => {
|
|
37
|
+
if (this.#currentIds.has(objectId)) {
|
|
38
|
+
this.refresh();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
this.#space.on('objectDeleted', onObjectDeleted);
|
|
42
|
+
this.#unsubscribers.push(() => this.#space.off('objectDeleted', onObjectDeleted));
|
|
43
|
+
// Handle full resets
|
|
44
|
+
const onReset = () => this.refresh();
|
|
45
|
+
this.#space.on('reset', onReset);
|
|
46
|
+
this.#unsubscribers.push(() => this.#space.off('reset', onReset));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if an object matches the `where` filter.
|
|
50
|
+
*/
|
|
51
|
+
#matches(object) {
|
|
52
|
+
const where = this.#options.where;
|
|
53
|
+
if (!where)
|
|
54
|
+
return true;
|
|
55
|
+
for (const [key, value] of Object.entries(where)) {
|
|
56
|
+
if (object[key] !== value)
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Re-fetch the collection from the space.
|
|
63
|
+
*/
|
|
64
|
+
async refresh() {
|
|
65
|
+
this.loading = true;
|
|
66
|
+
try {
|
|
67
|
+
const findOptions = {
|
|
68
|
+
where: this.#options.where,
|
|
69
|
+
limit: this.#options.limit,
|
|
70
|
+
order: this.#options.order,
|
|
71
|
+
ephemeral: true, // Don't pollute conversation history
|
|
72
|
+
};
|
|
73
|
+
const { objects } = await this.#space.findObjects(findOptions);
|
|
74
|
+
this.objects = objects;
|
|
75
|
+
this.#currentIds = new Set(objects.map((o) => o.id));
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
this.loading = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Stop listening for updates and clean up.
|
|
83
|
+
*/
|
|
84
|
+
close() {
|
|
85
|
+
for (const unsub of this.#unsubscribers)
|
|
86
|
+
unsub();
|
|
87
|
+
this.#unsubscribers.length = 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
1
90
|
/**
|
|
2
91
|
* Minimal wrapper that adds reactive `interactions` to RoolSpace.
|
|
3
92
|
* All other properties and methods are proxied to the underlying space.
|
|
@@ -87,6 +176,20 @@ class ReactiveSpaceImpl {
|
|
|
87
176
|
// Events
|
|
88
177
|
on(...args) { return this.#space.on(...args); }
|
|
89
178
|
off(...args) { return this.#space.off(...args); }
|
|
179
|
+
// Reactive collections
|
|
180
|
+
/**
|
|
181
|
+
* Create a reactive collection that auto-updates when matching objects change.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* const articles = space.collection({ where: { type: 'article' } });
|
|
185
|
+
* // articles.objects is reactive
|
|
186
|
+
* // articles.loading indicates fetch status
|
|
187
|
+
* // articles.refresh() to manually re-fetch
|
|
188
|
+
* // articles.close() to stop listening
|
|
189
|
+
*/
|
|
190
|
+
collection(options) {
|
|
191
|
+
return new ReactiveCollectionImpl(this.#space, options);
|
|
192
|
+
}
|
|
90
193
|
// Advanced
|
|
91
194
|
rename(...args) { return this.#space.rename(...args); }
|
|
92
195
|
getData() { return this.#space.getData(); }
|