@rool-dev/svelte 0.2.0 → 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.
@@ -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 { wrapSpace } from './space.svelte.js';
2
+ export { wrapChannel } from './channel.svelte.js';
3
3
  export type { Rool } from './rool.svelte.js';
4
- export type { ReactiveSpace, ReactiveObject, ReactiveCollection, CollectionOptions } from './space.svelte.js';
5
- export type { RoolClientConfig, RoolSpace, RoolSpaceInfo, RoolObject, RoolUserRole, ConnectionState, ConversationInfo, CurrentUser, Interaction, FindObjectsOptions, PromptOptions, CreateObjectOptions, UpdateObjectOptions, } from '@rool-dev/sdk';
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
@@ -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,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG9G,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"}
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
@@ -1,4 +1,4 @@
1
1
  // Main export
2
2
  export { createRool, generateId } from './rool.svelte.js';
3
- // Reactive space wrapper
4
- export { wrapSpace } from './space.svelte.js';
3
+ // Reactive channel wrapper
4
+ export { wrapChannel } from './channel.svelte.js';
@@ -1,5 +1,5 @@
1
- import { type RoolSpaceInfo, type ConnectionState, type RoolClientConfig, type CurrentUser } from '@rool-dev/sdk';
2
- import { type ReactiveSpace } from './space.svelte.js';
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
- * - Direct access to SDK spaces (no wrapper abstraction)
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 spaces.
32
+ * Log out and close all open channels.
33
33
  */
34
34
  logout(): void;
35
35
  /**
36
- * Open an existing space. Returns a ReactiveSpace with reactive `interactions`.
36
+ * Open a channel (space + channelId pair).
37
+ * Returns a ReactiveChannel with reactive `interactions`.
37
38
  */
38
- openSpace(id: string, options?: {
39
- conversationId?: string;
40
- }): Promise<ReactiveSpace>;
39
+ openChannel(spaceId: string, channelId: string): Promise<ReactiveChannel>;
41
40
  /**
42
- * Create a new space. Returns a ReactiveSpace with reactive `interactions`.
41
+ * Open a space for admin operations.
42
+ * Returns a lightweight RoolSpace handle (not reactive).
43
43
  */
44
- createSpace(name?: string, options?: {
45
- conversationId?: string;
46
- }): Promise<ReactiveSpace>;
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 ReactiveSpace with reactive `interactions`.
69
+ * Returns a lightweight RoolSpace handle (not reactive).
67
70
  */
68
- importArchive(name: string, archive: Blob, options?: {
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;AAC9H,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;;;;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;;OAEG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAO1F;;OAEG;IACG,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAO/F;;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;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,EACb,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GACpC,OAAO,CAAC,aAAa,CAAC;IAOzB;;OAEG;IACH,IAAI,QAAQ,qCAEX;IAED;;OAEG;IACH,cAAc;IAId;;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"}
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"}
@@ -1,5 +1,5 @@
1
1
  import { RoolClient } from '@rool-dev/sdk';
2
- import { wrapSpace } from './space.svelte.js';
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
- * - Direct access to SDK spaces (no wrapper abstraction)
10
+ * - Channel-based access to spaces
11
11
  */
12
12
  class RoolImpl {
13
13
  #client;
14
14
  #unsubscribers = [];
15
- #openSpaces = new Set();
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 spaces.
100
+ * Log out and close all open channels.
101
101
  */
102
102
  logout() {
103
- for (const space of this.#openSpaces) {
104
- space.close();
103
+ for (const channel of this.#openChannels) {
104
+ channel.close();
105
105
  }
106
- this.#openSpaces.clear();
106
+ this.#openChannels.clear();
107
107
  this.#client.logout();
108
108
  }
109
109
  /**
110
- * Open an existing space. Returns a ReactiveSpace with reactive `interactions`.
110
+ * Open a channel (space + channelId pair).
111
+ * Returns a ReactiveChannel with reactive `interactions`.
111
112
  */
112
- async openSpace(id, options) {
113
- const space = await this.#client.openSpace(id, options);
114
- const reactiveSpace = wrapSpace(space);
115
- this.#openSpaces.add(reactiveSpace);
116
- return reactiveSpace;
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
- * Create a new space. Returns a ReactiveSpace with reactive `interactions`.
120
+ * Open a space for admin operations.
121
+ * Returns a lightweight RoolSpace handle (not reactive).
120
122
  */
121
- async createSpace(name, options) {
122
- const space = await this.#client.createSpace(name, options);
123
- const reactiveSpace = wrapSpace(space);
124
- this.#openSpaces.add(reactiveSpace);
125
- return reactiveSpace;
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 ReactiveSpace with reactive `interactions`.
161
+ * Returns a lightweight RoolSpace handle (not reactive).
156
162
  */
157
- async importArchive(name, archive, options) {
158
- const space = await this.#client.importArchive(name, archive, options);
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 space of this.#openSpaces) {
180
- space.close();
202
+ for (const channel of this.#openChannels) {
203
+ channel.close();
181
204
  }
182
- this.#openSpaces.clear();
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.2.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.2.0"
44
+ "@rool-dev/sdk": "0.3.0-dev.be25932"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "svelte": "^5.0.0"