@rool-dev/svelte 0.2.0-dev.f798776 → 0.3.0-dev.be25932
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 +165 -54
- package/dist/channel.svelte.d.ts +143 -0
- package/dist/channel.svelte.d.ts.map +1 -0
- package/dist/channel.svelte.js +343 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/rool.svelte.d.ts +31 -16
- package/dist/rool.svelte.d.ts.map +1 -1
- package/dist/rool.svelte.js +51 -28
- package/package.json +2 -2
- package/dist/space.svelte.d.ts +0 -144
- package/dist/space.svelte.d.ts.map +0 -1
- package/dist/space.svelte.js +0 -311
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A reactive watch of objects that auto-updates when matching objects change.
|
|
3
|
+
*/
|
|
4
|
+
class ReactiveWatchImpl {
|
|
5
|
+
#channel;
|
|
6
|
+
#options;
|
|
7
|
+
#unsubscribers = [];
|
|
8
|
+
#currentIds = new Set();
|
|
9
|
+
// Reactive state
|
|
10
|
+
objects = $state([]);
|
|
11
|
+
loading = $state(true);
|
|
12
|
+
constructor(channel, options) {
|
|
13
|
+
this.#channel = channel;
|
|
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.#channel.on('objectCreated', onObjectCreated);
|
|
27
|
+
this.#unsubscribers.push(() => this.#channel.off('objectCreated', onObjectCreated));
|
|
28
|
+
const onObjectUpdated = ({ objectId, object }) => {
|
|
29
|
+
const wasInCollection = this.#currentIds.has(objectId);
|
|
30
|
+
const nowMatches = this.#matches(object);
|
|
31
|
+
if (wasInCollection && nowMatches) {
|
|
32
|
+
// Update in place
|
|
33
|
+
const index = this.objects.findIndex((o) => o.id === objectId);
|
|
34
|
+
if (index !== -1) {
|
|
35
|
+
this.objects[index] = object;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (wasInCollection && !nowMatches) {
|
|
39
|
+
// Remove from collection
|
|
40
|
+
this.objects = this.objects.filter((o) => o.id !== objectId);
|
|
41
|
+
this.#currentIds.delete(objectId);
|
|
42
|
+
}
|
|
43
|
+
else if (!wasInCollection && nowMatches) {
|
|
44
|
+
// Add to collection (re-fetch to respect limit/order)
|
|
45
|
+
this.refresh();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
this.#channel.on('objectUpdated', onObjectUpdated);
|
|
49
|
+
this.#unsubscribers.push(() => this.#channel.off('objectUpdated', onObjectUpdated));
|
|
50
|
+
const onObjectDeleted = ({ objectId }) => {
|
|
51
|
+
if (this.#currentIds.has(objectId)) {
|
|
52
|
+
this.objects = this.objects.filter((o) => o.id !== objectId);
|
|
53
|
+
this.#currentIds.delete(objectId);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
this.#channel.on('objectDeleted', onObjectDeleted);
|
|
57
|
+
this.#unsubscribers.push(() => this.#channel.off('objectDeleted', onObjectDeleted));
|
|
58
|
+
// Handle full resets
|
|
59
|
+
const onReset = () => this.refresh();
|
|
60
|
+
this.#channel.on('reset', onReset);
|
|
61
|
+
this.#unsubscribers.push(() => this.#channel.off('reset', onReset));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if an object matches the `where` filter.
|
|
65
|
+
*/
|
|
66
|
+
#matches(object) {
|
|
67
|
+
const where = this.#options.where;
|
|
68
|
+
if (!where)
|
|
69
|
+
return true;
|
|
70
|
+
for (const [key, value] of Object.entries(where)) {
|
|
71
|
+
if (object[key] !== value)
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Re-fetch the watched objects from the channel.
|
|
78
|
+
*/
|
|
79
|
+
async refresh() {
|
|
80
|
+
this.loading = true;
|
|
81
|
+
try {
|
|
82
|
+
const findOptions = {
|
|
83
|
+
where: this.#options.where,
|
|
84
|
+
limit: this.#options.limit,
|
|
85
|
+
order: this.#options.order,
|
|
86
|
+
ephemeral: true, // Don't pollute conversation history
|
|
87
|
+
};
|
|
88
|
+
const { objects } = await this.#channel.findObjects(findOptions);
|
|
89
|
+
this.objects = objects;
|
|
90
|
+
this.#currentIds = new Set(objects.map((o) => o.id));
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
this.loading = false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Stop listening for updates and clean up.
|
|
98
|
+
*/
|
|
99
|
+
close() {
|
|
100
|
+
for (const unsub of this.#unsubscribers)
|
|
101
|
+
unsub();
|
|
102
|
+
this.#unsubscribers.length = 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A reactive single object that auto-updates when the object changes.
|
|
107
|
+
*/
|
|
108
|
+
class ReactiveObjectImpl {
|
|
109
|
+
#channel;
|
|
110
|
+
#objectId;
|
|
111
|
+
#unsubscribers = [];
|
|
112
|
+
// Reactive state
|
|
113
|
+
data = $state(undefined);
|
|
114
|
+
loading = $state(true);
|
|
115
|
+
constructor(channel, objectId) {
|
|
116
|
+
this.#channel = channel;
|
|
117
|
+
this.#objectId = objectId;
|
|
118
|
+
this.#setup();
|
|
119
|
+
}
|
|
120
|
+
#setup() {
|
|
121
|
+
// Initial fetch
|
|
122
|
+
this.refresh();
|
|
123
|
+
// Listen for updates to this specific object
|
|
124
|
+
const onObjectUpdated = ({ objectId, object }) => {
|
|
125
|
+
if (objectId === this.#objectId) {
|
|
126
|
+
this.data = object;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
this.#channel.on('objectUpdated', onObjectUpdated);
|
|
130
|
+
this.#unsubscribers.push(() => this.#channel.off('objectUpdated', onObjectUpdated));
|
|
131
|
+
// Listen for creation (in case object didn't exist initially)
|
|
132
|
+
const onObjectCreated = ({ object }) => {
|
|
133
|
+
if (object.id === this.#objectId) {
|
|
134
|
+
this.data = object;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
this.#channel.on('objectCreated', onObjectCreated);
|
|
138
|
+
this.#unsubscribers.push(() => this.#channel.off('objectCreated', onObjectCreated));
|
|
139
|
+
// Listen for deletion
|
|
140
|
+
const onObjectDeleted = ({ objectId }) => {
|
|
141
|
+
if (objectId === this.#objectId) {
|
|
142
|
+
this.data = undefined;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
this.#channel.on('objectDeleted', onObjectDeleted);
|
|
146
|
+
this.#unsubscribers.push(() => this.#channel.off('objectDeleted', onObjectDeleted));
|
|
147
|
+
// Handle full resets
|
|
148
|
+
const onReset = () => this.refresh();
|
|
149
|
+
this.#channel.on('reset', onReset);
|
|
150
|
+
this.#unsubscribers.push(() => this.#channel.off('reset', onReset));
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Re-fetch the object from the channel.
|
|
154
|
+
*/
|
|
155
|
+
async refresh() {
|
|
156
|
+
this.loading = true;
|
|
157
|
+
try {
|
|
158
|
+
this.data = await this.#channel.getObject(this.#objectId);
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
this.loading = false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Stop listening for updates and clean up.
|
|
166
|
+
*/
|
|
167
|
+
close() {
|
|
168
|
+
for (const unsub of this.#unsubscribers)
|
|
169
|
+
unsub();
|
|
170
|
+
this.#unsubscribers.length = 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Minimal wrapper that adds reactive `interactions` to RoolChannel.
|
|
175
|
+
* All other properties and methods are proxied to the underlying channel.
|
|
176
|
+
*/
|
|
177
|
+
class ReactiveChannelImpl {
|
|
178
|
+
#channel;
|
|
179
|
+
#unsubscribers = [];
|
|
180
|
+
#closed = false;
|
|
181
|
+
// Reactive state
|
|
182
|
+
interactions = $state([]);
|
|
183
|
+
constructor(channel) {
|
|
184
|
+
this.#channel = channel;
|
|
185
|
+
this.interactions = channel.getInteractions();
|
|
186
|
+
// Subscribe to channel updates
|
|
187
|
+
const onChannelUpdated = () => {
|
|
188
|
+
this.interactions = channel.getInteractions();
|
|
189
|
+
};
|
|
190
|
+
channel.on('channelUpdated', onChannelUpdated);
|
|
191
|
+
this.#unsubscribers.push(() => channel.off('channelUpdated', onChannelUpdated));
|
|
192
|
+
const onReset = () => {
|
|
193
|
+
this.interactions = channel.getInteractions();
|
|
194
|
+
};
|
|
195
|
+
channel.on('reset', onReset);
|
|
196
|
+
this.#unsubscribers.push(() => channel.off('reset', onReset));
|
|
197
|
+
}
|
|
198
|
+
// Proxy read-only properties
|
|
199
|
+
get id() { return this.#channel.id; }
|
|
200
|
+
get name() { return this.#channel.name; }
|
|
201
|
+
get role() { return this.#channel.role; }
|
|
202
|
+
get userId() { return this.#channel.userId; }
|
|
203
|
+
get channelId() { return this.#channel.channelId; }
|
|
204
|
+
get isReadOnly() { return this.#channel.isReadOnly; }
|
|
205
|
+
get linkAccess() { return this.#channel.linkAccess; }
|
|
206
|
+
// Proxy all methods
|
|
207
|
+
close() {
|
|
208
|
+
this.#closed = true;
|
|
209
|
+
for (const unsub of this.#unsubscribers)
|
|
210
|
+
unsub();
|
|
211
|
+
this.#unsubscribers.length = 0;
|
|
212
|
+
this.#channel.close();
|
|
213
|
+
}
|
|
214
|
+
// Object operations
|
|
215
|
+
getObject(...args) { return this.#channel.getObject(...args); }
|
|
216
|
+
stat(...args) { return this.#channel.stat(...args); }
|
|
217
|
+
findObjects(...args) { return this.#channel.findObjects(...args); }
|
|
218
|
+
getObjectIds(...args) { return this.#channel.getObjectIds(...args); }
|
|
219
|
+
createObject(...args) { return this.#channel.createObject(...args); }
|
|
220
|
+
updateObject(...args) { return this.#channel.updateObject(...args); }
|
|
221
|
+
deleteObjects(...args) { return this.#channel.deleteObjects(...args); }
|
|
222
|
+
// AI
|
|
223
|
+
prompt(...args) { return this.#channel.prompt(...args); }
|
|
224
|
+
// Undo/redo
|
|
225
|
+
checkpoint(...args) { return this.#channel.checkpoint(...args); }
|
|
226
|
+
canUndo() { return this.#channel.canUndo(); }
|
|
227
|
+
canRedo() { return this.#channel.canRedo(); }
|
|
228
|
+
undo() { return this.#channel.undo(); }
|
|
229
|
+
redo() { return this.#channel.redo(); }
|
|
230
|
+
clearHistory() { return this.#channel.clearHistory(); }
|
|
231
|
+
// Metadata
|
|
232
|
+
setMetadata(...args) { return this.#channel.setMetadata(...args); }
|
|
233
|
+
getMetadata(...args) { return this.#channel.getMetadata(...args); }
|
|
234
|
+
getAllMetadata() { return this.#channel.getAllMetadata(); }
|
|
235
|
+
// Channel history
|
|
236
|
+
getInteractions() { return this.#channel.getInteractions(); }
|
|
237
|
+
getSystemInstruction() { return this.#channel.getSystemInstruction(); }
|
|
238
|
+
setSystemInstruction(...args) { return this.#channel.setSystemInstruction(...args); }
|
|
239
|
+
// Schema
|
|
240
|
+
getSchema() { return this.#channel.getSchema(); }
|
|
241
|
+
createCollection(...args) { return this.#channel.createCollection(...args); }
|
|
242
|
+
alterCollection(...args) { return this.#channel.alterCollection(...args); }
|
|
243
|
+
dropCollection(...args) { return this.#channel.dropCollection(...args); }
|
|
244
|
+
// Media
|
|
245
|
+
uploadMedia(...args) { return this.#channel.uploadMedia(...args); }
|
|
246
|
+
fetchMedia(...args) { return this.#channel.fetchMedia(...args); }
|
|
247
|
+
deleteMedia(...args) { return this.#channel.deleteMedia(...args); }
|
|
248
|
+
listMedia() { return this.#channel.listMedia(); }
|
|
249
|
+
// Channel admin
|
|
250
|
+
rename(...args) { return this.#channel.rename(...args); }
|
|
251
|
+
// Events
|
|
252
|
+
on(...args) { return this.#channel.on(...args); }
|
|
253
|
+
off(...args) { return this.#channel.off(...args); }
|
|
254
|
+
// Reactive primitives
|
|
255
|
+
/**
|
|
256
|
+
* Create a reactive object that auto-updates when the object changes.
|
|
257
|
+
* Throws if the channel has been closed.
|
|
258
|
+
*/
|
|
259
|
+
object(objectId) {
|
|
260
|
+
if (this.#closed)
|
|
261
|
+
throw new Error('Cannot create reactive object: channel is closed');
|
|
262
|
+
return new ReactiveObjectImpl(this.#channel, objectId);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Create a reactive watch that auto-updates when matching objects change.
|
|
266
|
+
* Throws if the channel has been closed.
|
|
267
|
+
*/
|
|
268
|
+
watch(options) {
|
|
269
|
+
if (this.#closed)
|
|
270
|
+
throw new Error('Cannot create reactive watch: channel is closed');
|
|
271
|
+
return new ReactiveWatchImpl(this.#channel, options);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
export function wrapChannel(channel) {
|
|
275
|
+
return new ReactiveChannelImpl(channel);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* A reactive list of channels for a space that auto-updates via SSE events.
|
|
279
|
+
*/
|
|
280
|
+
class ReactiveChannelListImpl {
|
|
281
|
+
#client;
|
|
282
|
+
#spaceId;
|
|
283
|
+
#unsubscribers = [];
|
|
284
|
+
// Reactive state
|
|
285
|
+
list = $state([]);
|
|
286
|
+
loading = $state(true);
|
|
287
|
+
constructor(client, spaceId) {
|
|
288
|
+
this.#client = client;
|
|
289
|
+
this.#spaceId = spaceId;
|
|
290
|
+
this.#setup();
|
|
291
|
+
}
|
|
292
|
+
#setup() {
|
|
293
|
+
// Initial fetch
|
|
294
|
+
this.refresh();
|
|
295
|
+
// Listen for channel lifecycle events
|
|
296
|
+
const onChannelCreated = (spaceId, channel) => {
|
|
297
|
+
if (spaceId !== this.#spaceId)
|
|
298
|
+
return;
|
|
299
|
+
this.list = [...this.list, channel];
|
|
300
|
+
};
|
|
301
|
+
this.#client.on('channelCreated', onChannelCreated);
|
|
302
|
+
this.#unsubscribers.push(() => this.#client.off('channelCreated', onChannelCreated));
|
|
303
|
+
const onChannelRenamed = (spaceId, channelId, newName) => {
|
|
304
|
+
if (spaceId !== this.#spaceId)
|
|
305
|
+
return;
|
|
306
|
+
this.list = this.list.map(ch => ch.id === channelId ? { ...ch, name: newName } : ch);
|
|
307
|
+
};
|
|
308
|
+
this.#client.on('channelRenamed', onChannelRenamed);
|
|
309
|
+
this.#unsubscribers.push(() => this.#client.off('channelRenamed', onChannelRenamed));
|
|
310
|
+
const onChannelDeleted = (spaceId, channelId) => {
|
|
311
|
+
if (spaceId !== this.#spaceId)
|
|
312
|
+
return;
|
|
313
|
+
this.list = this.list.filter(ch => ch.id !== channelId);
|
|
314
|
+
};
|
|
315
|
+
this.#client.on('channelDeleted', onChannelDeleted);
|
|
316
|
+
this.#unsubscribers.push(() => this.#client.off('channelDeleted', onChannelDeleted));
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Re-fetch the channel list from the server.
|
|
320
|
+
* Opens a lightweight space handle to get the channel list.
|
|
321
|
+
*/
|
|
322
|
+
async refresh() {
|
|
323
|
+
this.loading = true;
|
|
324
|
+
try {
|
|
325
|
+
const space = await this.#client.openSpace(this.#spaceId);
|
|
326
|
+
this.list = space.getChannels();
|
|
327
|
+
}
|
|
328
|
+
finally {
|
|
329
|
+
this.loading = false;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Stop listening for updates and clean up.
|
|
334
|
+
*/
|
|
335
|
+
close() {
|
|
336
|
+
for (const unsub of this.#unsubscribers)
|
|
337
|
+
unsub();
|
|
338
|
+
this.#unsubscribers.length = 0;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
export function createChannelList(client, spaceId) {
|
|
342
|
+
return new ReactiveChannelListImpl(client, spaceId);
|
|
343
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createRool, generateId } from './rool.svelte.js';
|
|
2
|
-
export {
|
|
2
|
+
export { wrapChannel } from './channel.svelte.js';
|
|
3
3
|
export type { Rool } from './rool.svelte.js';
|
|
4
|
-
export type {
|
|
5
|
-
export type { RoolClientConfig, RoolSpace, RoolSpaceInfo, RoolObject, RoolUserRole, ConnectionState,
|
|
4
|
+
export type { ReactiveChannel, ReactiveObject, ReactiveWatch, ReactiveChannelList, WatchOptions } from './channel.svelte.js';
|
|
5
|
+
export type { RoolClientConfig, RoolChannel, RoolSpace, RoolSpaceInfo, RoolObject, RoolUserRole, ConnectionState, ChannelInfo, CurrentUser, Interaction, FindObjectsOptions, PromptOptions, CreateObjectOptions, UpdateObjectOptions, FieldType, FieldDef, CollectionDef, SpaceSchema, } 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,
|
|
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,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAG7H,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,EACZ,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/rool.svelte.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type RoolSpaceInfo, type ConnectionState, type RoolClientConfig, type CurrentUser } from '@rool-dev/sdk';
|
|
2
|
-
import { type
|
|
1
|
+
import { type RoolSpace, type RoolSpaceInfo, type ConnectionState, type RoolClientConfig, type CurrentUser } from '@rool-dev/sdk';
|
|
2
|
+
import { type ReactiveChannel, type ReactiveChannelList } from './channel.svelte.js';
|
|
3
3
|
/**
|
|
4
4
|
* Rool client with reactive state for Svelte 5.
|
|
5
5
|
*
|
|
@@ -7,7 +7,7 @@ import { type ReactiveSpace } from './space.svelte.js';
|
|
|
7
7
|
* - Reactive auth state (`authenticated`)
|
|
8
8
|
* - Reactive spaces list (`spaces`)
|
|
9
9
|
* - Reactive user storage (`userStorage`)
|
|
10
|
-
* -
|
|
10
|
+
* - Channel-based access to spaces
|
|
11
11
|
*/
|
|
12
12
|
declare class RoolImpl {
|
|
13
13
|
#private;
|
|
@@ -29,21 +29,24 @@ declare class RoolImpl {
|
|
|
29
29
|
*/
|
|
30
30
|
login(appName: string): void;
|
|
31
31
|
/**
|
|
32
|
-
* Log out and close all open
|
|
32
|
+
* Log out and close all open channels.
|
|
33
33
|
*/
|
|
34
34
|
logout(): void;
|
|
35
35
|
/**
|
|
36
|
-
* Open
|
|
36
|
+
* Open a channel (space + channelId pair).
|
|
37
|
+
* Returns a ReactiveChannel with reactive `interactions`.
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
|
-
conversationId?: string;
|
|
40
|
-
}): Promise<ReactiveSpace>;
|
|
39
|
+
openChannel(spaceId: string, channelId: string): Promise<ReactiveChannel>;
|
|
41
40
|
/**
|
|
42
|
-
*
|
|
41
|
+
* Open a space for admin operations.
|
|
42
|
+
* Returns a lightweight RoolSpace handle (not reactive).
|
|
43
43
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
openSpace(spaceId: string): Promise<RoolSpace>;
|
|
45
|
+
/**
|
|
46
|
+
* Create a new space.
|
|
47
|
+
* Returns a lightweight RoolSpace handle (not reactive).
|
|
48
|
+
*/
|
|
49
|
+
createSpace(name: string): Promise<RoolSpace>;
|
|
47
50
|
/**
|
|
48
51
|
* Manually refresh the spaces list.
|
|
49
52
|
*/
|
|
@@ -63,11 +66,9 @@ declare class RoolImpl {
|
|
|
63
66
|
searchUser(email: string): Promise<import("@rool-dev/sdk").UserResult | null>;
|
|
64
67
|
/**
|
|
65
68
|
* Import a space from a zip archive.
|
|
66
|
-
* Returns a
|
|
69
|
+
* Returns a lightweight RoolSpace handle (not reactive).
|
|
67
70
|
*/
|
|
68
|
-
importArchive(name: string, archive: Blob
|
|
69
|
-
conversationId?: string;
|
|
70
|
-
}): Promise<ReactiveSpace>;
|
|
71
|
+
importArchive(name: string, archive: Blob): Promise<RoolSpace>;
|
|
71
72
|
/**
|
|
72
73
|
* Get auth user info from JWT token.
|
|
73
74
|
*/
|
|
@@ -76,6 +77,20 @@ declare class RoolImpl {
|
|
|
76
77
|
* Get current user profile from server.
|
|
77
78
|
*/
|
|
78
79
|
getCurrentUser(): Promise<CurrentUser>;
|
|
80
|
+
/**
|
|
81
|
+
* Rename a channel (conversation) in a space.
|
|
82
|
+
*/
|
|
83
|
+
renameChannel(spaceId: string, channelId: string, name: string): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Delete a channel (conversation) from a space.
|
|
86
|
+
*/
|
|
87
|
+
deleteChannel(spaceId: string, channelId: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Create a reactive channel list for a space.
|
|
90
|
+
* Auto-updates when channels are created, renamed, or deleted.
|
|
91
|
+
* Call close() when done to stop listening.
|
|
92
|
+
*/
|
|
93
|
+
channels(spaceId: string): ReactiveChannelList;
|
|
79
94
|
/**
|
|
80
95
|
* Clean up resources.
|
|
81
96
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rool.svelte.d.ts","sourceRoot":"","sources":["../src/rool.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"rool.svelte.d.ts","sourceRoot":"","sources":["../src/rool.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9I,OAAO,EAAkC,KAAK,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAErH;;;;;;;;GAQG;AACH,cAAM,QAAQ;;IAMZ,aAAa,iBAAgC;IAC7C,MAAM,8BAAkD;IACxD,aAAa,UAAiB;IAC9B,WAAW,eAA8B;IACzC,eAAe,kBAA2C;IAC1D,WAAW,0BAAuC;IAClD,WAAW,qBAAoC;gBAEnC,MAAM,CAAC,EAAE,gBAAgB;IA2DrC;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAW9B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO/E;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAI9C;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAI7C;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C;;;OAGG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAKjD;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM;IAIxB;;;OAGG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;IAI9D;;OAEG;IACH,IAAI,QAAQ,qCAEX;IAED;;OAEG;IACH,cAAc;IAId;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9E;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB;IAI9C;;OAEG;IACH,OAAO,IAAI,IAAI;CAahB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAE1D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,MAAM,MAAM,IAAI,GAAG,QAAQ,CAAC"}
|
package/dist/rool.svelte.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RoolClient } from '@rool-dev/sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { wrapChannel, createChannelList } from './channel.svelte.js';
|
|
3
3
|
/**
|
|
4
4
|
* Rool client with reactive state for Svelte 5.
|
|
5
5
|
*
|
|
@@ -7,12 +7,12 @@ import { wrapSpace } from './space.svelte.js';
|
|
|
7
7
|
* - Reactive auth state (`authenticated`)
|
|
8
8
|
* - Reactive spaces list (`spaces`)
|
|
9
9
|
* - Reactive user storage (`userStorage`)
|
|
10
|
-
* -
|
|
10
|
+
* - Channel-based access to spaces
|
|
11
11
|
*/
|
|
12
12
|
class RoolImpl {
|
|
13
13
|
#client;
|
|
14
14
|
#unsubscribers = [];
|
|
15
|
-
#
|
|
15
|
+
#openChannels = new Set();
|
|
16
16
|
// Reactive state
|
|
17
17
|
authenticated = $state(null); // null = checking, false = not auth, true = auth
|
|
18
18
|
spaces = $state(undefined);
|
|
@@ -97,32 +97,38 @@ class RoolImpl {
|
|
|
97
97
|
this.#client.login(appName);
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
|
-
* Log out and close all open
|
|
100
|
+
* Log out and close all open channels.
|
|
101
101
|
*/
|
|
102
102
|
logout() {
|
|
103
|
-
for (const
|
|
104
|
-
|
|
103
|
+
for (const channel of this.#openChannels) {
|
|
104
|
+
channel.close();
|
|
105
105
|
}
|
|
106
|
-
this.#
|
|
106
|
+
this.#openChannels.clear();
|
|
107
107
|
this.#client.logout();
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
|
-
* Open
|
|
110
|
+
* Open a channel (space + channelId pair).
|
|
111
|
+
* Returns a ReactiveChannel with reactive `interactions`.
|
|
111
112
|
*/
|
|
112
|
-
async
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
this.#
|
|
116
|
-
return
|
|
113
|
+
async openChannel(spaceId, channelId) {
|
|
114
|
+
const channel = await this.#client.openChannel(spaceId, channelId);
|
|
115
|
+
const reactiveChannel = wrapChannel(channel);
|
|
116
|
+
this.#openChannels.add(reactiveChannel);
|
|
117
|
+
return reactiveChannel;
|
|
117
118
|
}
|
|
118
119
|
/**
|
|
119
|
-
*
|
|
120
|
+
* Open a space for admin operations.
|
|
121
|
+
* Returns a lightweight RoolSpace handle (not reactive).
|
|
120
122
|
*/
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
openSpace(spaceId) {
|
|
124
|
+
return this.#client.openSpace(spaceId);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Create a new space.
|
|
128
|
+
* Returns a lightweight RoolSpace handle (not reactive).
|
|
129
|
+
*/
|
|
130
|
+
createSpace(name) {
|
|
131
|
+
return this.#client.createSpace(name);
|
|
126
132
|
}
|
|
127
133
|
/**
|
|
128
134
|
* Manually refresh the spaces list.
|
|
@@ -152,13 +158,10 @@ class RoolImpl {
|
|
|
152
158
|
}
|
|
153
159
|
/**
|
|
154
160
|
* Import a space from a zip archive.
|
|
155
|
-
* Returns a
|
|
161
|
+
* Returns a lightweight RoolSpace handle (not reactive).
|
|
156
162
|
*/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const reactiveSpace = wrapSpace(space);
|
|
160
|
-
this.#openSpaces.add(reactiveSpace);
|
|
161
|
-
return reactiveSpace;
|
|
163
|
+
importArchive(name, archive) {
|
|
164
|
+
return this.#client.importArchive(name, archive);
|
|
162
165
|
}
|
|
163
166
|
/**
|
|
164
167
|
* Get auth user info from JWT token.
|
|
@@ -172,14 +175,34 @@ class RoolImpl {
|
|
|
172
175
|
getCurrentUser() {
|
|
173
176
|
return this.#client.getCurrentUser();
|
|
174
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Rename a channel (conversation) in a space.
|
|
180
|
+
*/
|
|
181
|
+
renameChannel(spaceId, channelId, name) {
|
|
182
|
+
return this.#client.renameChannel(spaceId, channelId, name);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Delete a channel (conversation) from a space.
|
|
186
|
+
*/
|
|
187
|
+
deleteChannel(spaceId, channelId) {
|
|
188
|
+
return this.#client.deleteChannel(spaceId, channelId);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Create a reactive channel list for a space.
|
|
192
|
+
* Auto-updates when channels are created, renamed, or deleted.
|
|
193
|
+
* Call close() when done to stop listening.
|
|
194
|
+
*/
|
|
195
|
+
channels(spaceId) {
|
|
196
|
+
return createChannelList(this.#client, spaceId);
|
|
197
|
+
}
|
|
175
198
|
/**
|
|
176
199
|
* Clean up resources.
|
|
177
200
|
*/
|
|
178
201
|
destroy() {
|
|
179
|
-
for (const
|
|
180
|
-
|
|
202
|
+
for (const channel of this.#openChannels) {
|
|
203
|
+
channel.close();
|
|
181
204
|
}
|
|
182
|
-
this.#
|
|
205
|
+
this.#openChannels.clear();
|
|
183
206
|
for (const unsub of this.#unsubscribers) {
|
|
184
207
|
unsub();
|
|
185
208
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rool-dev/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-dev.be25932",
|
|
4
4
|
"description": "Svelte 5 runes for Rool Spaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT",
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@rool-dev/sdk": "0.
|
|
44
|
+
"@rool-dev/sdk": "0.3.0-dev.be25932"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"svelte": "^5.0.0"
|