@rool-dev/extension 0.3.5
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 +458 -0
- package/dist/cli/build-pipeline.d.ts +18 -0
- package/dist/cli/build-pipeline.d.ts.map +1 -0
- package/dist/cli/build-pipeline.js +160 -0
- package/dist/cli/build.d.ts +9 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +17 -0
- package/dist/cli/dev.d.ts +10 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/dev.js +257 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +34 -0
- package/dist/cli/init.d.ts +8 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +113 -0
- package/dist/cli/publish.d.ts +9 -0
- package/dist/cli/publish.d.ts.map +1 -0
- package/dist/cli/publish.js +65 -0
- package/dist/cli/vite-utils.d.ts +23 -0
- package/dist/cli/vite-utils.d.ts.map +1 -0
- package/dist/cli/vite-utils.js +105 -0
- package/dist/client.d.ts +139 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +360 -0
- package/dist/dev/AppGrid.svelte +246 -0
- package/dist/dev/AppGrid.svelte.d.ts +14 -0
- package/dist/dev/AppGrid.svelte.d.ts.map +1 -0
- package/dist/dev/DevHostController.d.ts +85 -0
- package/dist/dev/DevHostController.d.ts.map +1 -0
- package/dist/dev/DevHostController.js +429 -0
- package/dist/dev/HostShell.svelte +119 -0
- package/dist/dev/HostShell.svelte.d.ts +11 -0
- package/dist/dev/HostShell.svelte.d.ts.map +1 -0
- package/dist/dev/Sidebar.svelte +290 -0
- package/dist/dev/Sidebar.svelte.d.ts +22 -0
- package/dist/dev/Sidebar.svelte.d.ts.map +1 -0
- package/dist/dev/TabBar.svelte +83 -0
- package/dist/dev/TabBar.svelte.d.ts +14 -0
- package/dist/dev/TabBar.svelte.d.ts.map +1 -0
- package/dist/dev/app.css +1 -0
- package/dist/dev/host-shell.d.ts +8 -0
- package/dist/dev/host-shell.d.ts.map +1 -0
- package/dist/dev/host-shell.js +15282 -0
- package/dist/dev/host-shell.js.map +1 -0
- package/dist/dev/vite-env.d.ts +4 -0
- package/dist/host.d.ts +55 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +203 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/manifest.d.ts +40 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +11 -0
- package/dist/protocol.d.ts +48 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +14 -0
- package/dist/reactive.svelte.d.ts +150 -0
- package/dist/reactive.svelte.d.ts.map +1 -0
- package/dist/reactive.svelte.js +362 -0
- package/dist/types.d.ts +139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/package.json +79 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reactive Svelte wrapper around Channel (bridge client).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the @rool-dev/svelte ReactiveChannel API: same $state properties,
|
|
5
|
+
* same methods, same reactive primitives (object(), watch()).
|
|
6
|
+
* The underlying transport is the postMessage bridge, not the SDK.
|
|
7
|
+
*/
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// ReactiveWatch
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
class ReactiveWatchImpl {
|
|
12
|
+
#channel;
|
|
13
|
+
#options;
|
|
14
|
+
#unsubscribers = [];
|
|
15
|
+
#currentIds = new Set();
|
|
16
|
+
objects = $state([]);
|
|
17
|
+
loading = $state(true);
|
|
18
|
+
constructor(channel, options) {
|
|
19
|
+
this.#channel = channel;
|
|
20
|
+
this.#options = options;
|
|
21
|
+
this.#setup();
|
|
22
|
+
}
|
|
23
|
+
#setup() {
|
|
24
|
+
this.refresh();
|
|
25
|
+
const onObjectCreated = ({ object }) => {
|
|
26
|
+
if (this.#matches(object))
|
|
27
|
+
this.refresh();
|
|
28
|
+
};
|
|
29
|
+
this.#channel.on('objectCreated', onObjectCreated);
|
|
30
|
+
this.#unsubscribers.push(() => this.#channel.off('objectCreated', onObjectCreated));
|
|
31
|
+
const onObjectUpdated = ({ objectId, object }) => {
|
|
32
|
+
const wasIn = this.#currentIds.has(objectId);
|
|
33
|
+
const nowMatches = this.#matches(object);
|
|
34
|
+
if (wasIn && nowMatches) {
|
|
35
|
+
const i = this.objects.findIndex((o) => o.id === objectId);
|
|
36
|
+
if (i !== -1)
|
|
37
|
+
this.objects[i] = { ...this.objects[i], ...object };
|
|
38
|
+
}
|
|
39
|
+
else if (wasIn && !nowMatches) {
|
|
40
|
+
const where = this.#options.where;
|
|
41
|
+
const isPartial = where && Object.keys(where).some((k) => !(k in object));
|
|
42
|
+
if (isPartial) {
|
|
43
|
+
const i = this.objects.findIndex((o) => o.id === objectId);
|
|
44
|
+
if (i !== -1)
|
|
45
|
+
this.objects[i] = { ...this.objects[i], ...object };
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.objects = this.objects.filter((o) => o.id !== objectId);
|
|
49
|
+
this.#currentIds.delete(objectId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (!wasIn && nowMatches) {
|
|
53
|
+
this.refresh();
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
this.#channel.on('objectUpdated', onObjectUpdated);
|
|
57
|
+
this.#unsubscribers.push(() => this.#channel.off('objectUpdated', onObjectUpdated));
|
|
58
|
+
const onObjectDeleted = ({ objectId }) => {
|
|
59
|
+
if (this.#currentIds.has(objectId)) {
|
|
60
|
+
this.objects = this.objects.filter((o) => o.id !== objectId);
|
|
61
|
+
this.#currentIds.delete(objectId);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
this.#channel.on('objectDeleted', onObjectDeleted);
|
|
65
|
+
this.#unsubscribers.push(() => this.#channel.off('objectDeleted', onObjectDeleted));
|
|
66
|
+
const onReset = () => this.refresh();
|
|
67
|
+
this.#channel.on('reset', onReset);
|
|
68
|
+
this.#unsubscribers.push(() => this.#channel.off('reset', onReset));
|
|
69
|
+
}
|
|
70
|
+
#matches(object) {
|
|
71
|
+
// Collection membership is shape-based and resolved server-side — can't match locally
|
|
72
|
+
if (this.#options.collection)
|
|
73
|
+
return true;
|
|
74
|
+
const where = this.#options.where;
|
|
75
|
+
if (!where)
|
|
76
|
+
return true;
|
|
77
|
+
for (const [key, value] of Object.entries(where)) {
|
|
78
|
+
if (object[key] !== value)
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
async refresh() {
|
|
84
|
+
this.loading = true;
|
|
85
|
+
try {
|
|
86
|
+
const { objects } = await this.#channel.findObjects({
|
|
87
|
+
where: this.#options.where,
|
|
88
|
+
collection: this.#options.collection,
|
|
89
|
+
limit: this.#options.limit,
|
|
90
|
+
order: this.#options.order,
|
|
91
|
+
ephemeral: true,
|
|
92
|
+
});
|
|
93
|
+
this.objects = objects;
|
|
94
|
+
this.#currentIds = new Set(objects.map((o) => o.id));
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
this.loading = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
close() {
|
|
101
|
+
for (const unsub of this.#unsubscribers)
|
|
102
|
+
unsub();
|
|
103
|
+
this.#unsubscribers.length = 0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// ReactiveObject
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
class ReactiveObjectImpl {
|
|
110
|
+
#channel;
|
|
111
|
+
#objectId;
|
|
112
|
+
#unsubscribers = [];
|
|
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
|
+
this.refresh();
|
|
122
|
+
const onObjectUpdated = ({ objectId, object }) => {
|
|
123
|
+
if (objectId === this.#objectId)
|
|
124
|
+
this.data = object;
|
|
125
|
+
};
|
|
126
|
+
this.#channel.on('objectUpdated', onObjectUpdated);
|
|
127
|
+
this.#unsubscribers.push(() => this.#channel.off('objectUpdated', onObjectUpdated));
|
|
128
|
+
const onObjectCreated = ({ object }) => {
|
|
129
|
+
if (object.id === this.#objectId)
|
|
130
|
+
this.data = object;
|
|
131
|
+
};
|
|
132
|
+
this.#channel.on('objectCreated', onObjectCreated);
|
|
133
|
+
this.#unsubscribers.push(() => this.#channel.off('objectCreated', onObjectCreated));
|
|
134
|
+
const onObjectDeleted = ({ objectId }) => {
|
|
135
|
+
if (objectId === this.#objectId)
|
|
136
|
+
this.data = undefined;
|
|
137
|
+
};
|
|
138
|
+
this.#channel.on('objectDeleted', onObjectDeleted);
|
|
139
|
+
this.#unsubscribers.push(() => this.#channel.off('objectDeleted', onObjectDeleted));
|
|
140
|
+
const onReset = () => this.refresh();
|
|
141
|
+
this.#channel.on('reset', onReset);
|
|
142
|
+
this.#unsubscribers.push(() => this.#channel.off('reset', onReset));
|
|
143
|
+
}
|
|
144
|
+
async refresh() {
|
|
145
|
+
this.loading = true;
|
|
146
|
+
try {
|
|
147
|
+
this.data = await this.#channel.getObject(this.#objectId);
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
this.loading = false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
close() {
|
|
154
|
+
for (const unsub of this.#unsubscribers)
|
|
155
|
+
unsub();
|
|
156
|
+
this.#unsubscribers.length = 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
// ReactiveChannel
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
class ReactiveChannelImpl {
|
|
163
|
+
#channel;
|
|
164
|
+
#closed = false;
|
|
165
|
+
// Reactive state
|
|
166
|
+
interactions = $state([]);
|
|
167
|
+
objectIds = $state([]);
|
|
168
|
+
collections = $state([]);
|
|
169
|
+
conversations = $state([]);
|
|
170
|
+
#unsubscribers = [];
|
|
171
|
+
constructor(channel) {
|
|
172
|
+
this.#channel = channel;
|
|
173
|
+
// Load initial data
|
|
174
|
+
channel.getInteractions().then((list) => { this.interactions = list; });
|
|
175
|
+
channel.getObjectIds().then((ids) => { this.objectIds = ids; });
|
|
176
|
+
channel.getConversations().then((list) => { this.conversations = list; });
|
|
177
|
+
this.collections = Object.keys(channel.getSchema());
|
|
178
|
+
// Subscribe to channel updates → refresh interactions
|
|
179
|
+
const onChannelUpdated = () => {
|
|
180
|
+
channel.getInteractions().then((list) => { this.interactions = list; });
|
|
181
|
+
};
|
|
182
|
+
channel.on('channelUpdated', onChannelUpdated);
|
|
183
|
+
this.#unsubscribers.push(() => channel.off('channelUpdated', onChannelUpdated));
|
|
184
|
+
// Subscribe to conversation updates → refresh conversations
|
|
185
|
+
const onConversationUpdated = () => {
|
|
186
|
+
channel.getConversations().then((list) => { this.conversations = list; });
|
|
187
|
+
};
|
|
188
|
+
channel.on('conversationUpdated', onConversationUpdated);
|
|
189
|
+
this.#unsubscribers.push(() => channel.off('conversationUpdated', onConversationUpdated));
|
|
190
|
+
// Subscribe to object events → refresh objectIds
|
|
191
|
+
const refreshObjectIds = () => {
|
|
192
|
+
channel.getObjectIds().then((ids) => { this.objectIds = ids; });
|
|
193
|
+
};
|
|
194
|
+
channel.on('objectCreated', refreshObjectIds);
|
|
195
|
+
this.#unsubscribers.push(() => channel.off('objectCreated', refreshObjectIds));
|
|
196
|
+
channel.on('objectDeleted', refreshObjectIds);
|
|
197
|
+
this.#unsubscribers.push(() => channel.off('objectDeleted', refreshObjectIds));
|
|
198
|
+
// Subscribe to schema updates → refresh collections
|
|
199
|
+
const onSchemaUpdated = () => {
|
|
200
|
+
this.collections = Object.keys(channel.getSchema());
|
|
201
|
+
};
|
|
202
|
+
channel.on('schemaUpdated', onSchemaUpdated);
|
|
203
|
+
this.#unsubscribers.push(() => channel.off('schemaUpdated', onSchemaUpdated));
|
|
204
|
+
// Full resets
|
|
205
|
+
const onReset = () => {
|
|
206
|
+
channel.getInteractions().then((list) => { this.interactions = list; });
|
|
207
|
+
channel.getObjectIds().then((ids) => { this.objectIds = ids; });
|
|
208
|
+
channel.getConversations().then((list) => { this.conversations = list; });
|
|
209
|
+
this.collections = Object.keys(channel.getSchema());
|
|
210
|
+
};
|
|
211
|
+
channel.on('reset', onReset);
|
|
212
|
+
this.#unsubscribers.push(() => channel.off('reset', onReset));
|
|
213
|
+
}
|
|
214
|
+
// Proxied properties
|
|
215
|
+
get channelId() { return this.#channel.channelId; }
|
|
216
|
+
get spaceId() { return this.#channel.spaceId; }
|
|
217
|
+
get spaceName() { return this.#channel.spaceName; }
|
|
218
|
+
get role() { return this.#channel.role; }
|
|
219
|
+
get linkAccess() { return this.#channel.linkAccess; }
|
|
220
|
+
get userId() { return this.#channel.userId; }
|
|
221
|
+
get isReadOnly() { return this.#channel.isReadOnly; }
|
|
222
|
+
// Object operations
|
|
223
|
+
getObject(objectId) { return this.#channel.getObject(objectId); }
|
|
224
|
+
stat(objectId) { return this.#channel.stat(objectId); }
|
|
225
|
+
findObjects(options) { return this.#channel.findObjects(options); }
|
|
226
|
+
getObjectIds(options) { return this.#channel.getObjectIds(options); }
|
|
227
|
+
createObject(options) { return this.#channel.createObject(options); }
|
|
228
|
+
updateObject(objectId, options) { return this.#channel.updateObject(objectId, options); }
|
|
229
|
+
deleteObjects(objectIds) { return this.#channel.deleteObjects(objectIds); }
|
|
230
|
+
// AI
|
|
231
|
+
prompt(text, options) { return this.#channel.prompt(text, options); }
|
|
232
|
+
// Undo/redo
|
|
233
|
+
checkpoint(label) { return this.#channel.checkpoint(label); }
|
|
234
|
+
canUndo() { return this.#channel.canUndo(); }
|
|
235
|
+
canRedo() { return this.#channel.canRedo(); }
|
|
236
|
+
undo() { return this.#channel.undo(); }
|
|
237
|
+
redo() { return this.#channel.redo(); }
|
|
238
|
+
clearHistory() { return this.#channel.clearHistory(); }
|
|
239
|
+
// Metadata
|
|
240
|
+
setMetadata(key, value) { return this.#channel.setMetadata(key, value); }
|
|
241
|
+
getMetadata(key) { return this.#channel.getMetadata(key); }
|
|
242
|
+
getAllMetadata() { return this.#channel.getAllMetadata(); }
|
|
243
|
+
// History
|
|
244
|
+
getInteractions() { return this.#channel.getInteractions(); }
|
|
245
|
+
getSystemInstruction() { return this.#channel.getSystemInstruction(); }
|
|
246
|
+
setSystemInstruction(instruction) { return this.#channel.setSystemInstruction(instruction); }
|
|
247
|
+
getConversations() { return this.#channel.getConversations(); }
|
|
248
|
+
deleteConversation(conversationId) { return this.#channel.deleteConversation(conversationId); }
|
|
249
|
+
renameConversation(name) { return this.#channel.renameConversation(name); }
|
|
250
|
+
// Schema
|
|
251
|
+
getSchema() { return this.#channel.getSchema(); }
|
|
252
|
+
createCollection(name, fields) { return this.#channel.createCollection(name, fields); }
|
|
253
|
+
alterCollection(name, fields) { return this.#channel.alterCollection(name, fields); }
|
|
254
|
+
dropCollection(name) { return this.#channel.dropCollection(name); }
|
|
255
|
+
// Conversations
|
|
256
|
+
conversation(conversationId) {
|
|
257
|
+
if (this.#closed)
|
|
258
|
+
throw new Error('Cannot create reactive conversation: channel is closed');
|
|
259
|
+
return new ReactiveConversationHandleImpl(this.#channel, conversationId);
|
|
260
|
+
}
|
|
261
|
+
// Events
|
|
262
|
+
on(...args) { return this.#channel.on(...args); }
|
|
263
|
+
off(...args) { return this.#channel.off(...args); }
|
|
264
|
+
// Reactive primitives
|
|
265
|
+
object(objectId) {
|
|
266
|
+
if (this.#closed)
|
|
267
|
+
throw new Error('Cannot create reactive object: channel is closed');
|
|
268
|
+
return new ReactiveObjectImpl(this.#channel, objectId);
|
|
269
|
+
}
|
|
270
|
+
watch(options) {
|
|
271
|
+
if (this.#closed)
|
|
272
|
+
throw new Error('Cannot create reactive watch: channel is closed');
|
|
273
|
+
return new ReactiveWatchImpl(this.#channel, options);
|
|
274
|
+
}
|
|
275
|
+
// Cleanup
|
|
276
|
+
destroy() {
|
|
277
|
+
this.#closed = true;
|
|
278
|
+
for (const unsub of this.#unsubscribers)
|
|
279
|
+
unsub();
|
|
280
|
+
this.#unsubscribers.length = 0;
|
|
281
|
+
this.#channel.destroy();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
// ReactiveConversationHandle
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
/**
|
|
288
|
+
* A reactive conversation handle for the extension bridge.
|
|
289
|
+
* Wraps ConversationHandle with $state interactions that auto-update
|
|
290
|
+
* when the conversation changes via SSE events.
|
|
291
|
+
*
|
|
292
|
+
* Call `close()` when done to stop listening for updates.
|
|
293
|
+
*/
|
|
294
|
+
class ReactiveConversationHandleImpl {
|
|
295
|
+
#handle;
|
|
296
|
+
#conversationId;
|
|
297
|
+
#unsubscribers = [];
|
|
298
|
+
// Reactive state
|
|
299
|
+
interactions = $state([]);
|
|
300
|
+
constructor(channel, conversationId) {
|
|
301
|
+
this.#conversationId = conversationId;
|
|
302
|
+
this.#handle = channel.conversation(conversationId);
|
|
303
|
+
// Initial load
|
|
304
|
+
this.#handle.getInteractions().then((list) => { this.interactions = list; });
|
|
305
|
+
// Listen for updates to this conversation
|
|
306
|
+
const onConversationUpdated = ({ conversationId: cid }) => {
|
|
307
|
+
if (cid === this.#conversationId) {
|
|
308
|
+
this.#handle.getInteractions().then((list) => { this.interactions = list; });
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
channel.on('conversationUpdated', onConversationUpdated);
|
|
312
|
+
this.#unsubscribers.push(() => channel.off('conversationUpdated', onConversationUpdated));
|
|
313
|
+
// Handle full resets
|
|
314
|
+
const onReset = () => {
|
|
315
|
+
this.#handle.getInteractions().then((list) => { this.interactions = list; });
|
|
316
|
+
};
|
|
317
|
+
channel.on('reset', onReset);
|
|
318
|
+
this.#unsubscribers.push(() => channel.off('reset', onReset));
|
|
319
|
+
}
|
|
320
|
+
get conversationId() { return this.#conversationId; }
|
|
321
|
+
// Conversation history
|
|
322
|
+
getInteractions() { return this.#handle.getInteractions(); }
|
|
323
|
+
getSystemInstruction() { return this.#handle.getSystemInstruction(); }
|
|
324
|
+
setSystemInstruction(instruction) { return this.#handle.setSystemInstruction(instruction); }
|
|
325
|
+
rename(name) { return this.#handle.rename(name); }
|
|
326
|
+
// Object operations
|
|
327
|
+
findObjects(options) { return this.#handle.findObjects(options); }
|
|
328
|
+
createObject(options) { return this.#handle.createObject(options); }
|
|
329
|
+
updateObject(objectId, options) { return this.#handle.updateObject(objectId, options); }
|
|
330
|
+
deleteObjects(objectIds) { return this.#handle.deleteObjects(objectIds); }
|
|
331
|
+
// AI
|
|
332
|
+
prompt(text, options) { return this.#handle.prompt(text, options); }
|
|
333
|
+
// Schema
|
|
334
|
+
createCollection(name, fields) { return this.#handle.createCollection(name, fields); }
|
|
335
|
+
alterCollection(name, fields) { return this.#handle.alterCollection(name, fields); }
|
|
336
|
+
dropCollection(name) { return this.#handle.dropCollection(name); }
|
|
337
|
+
// Metadata
|
|
338
|
+
setMetadata(key, value) { return this.#handle.setMetadata(key, value); }
|
|
339
|
+
/**
|
|
340
|
+
* Stop listening for updates and clean up.
|
|
341
|
+
*/
|
|
342
|
+
close() {
|
|
343
|
+
for (const unsub of this.#unsubscribers)
|
|
344
|
+
unsub();
|
|
345
|
+
this.#unsubscribers.length = 0;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// initExtension (reactive version)
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
import { initExtension as initBridge } from './client.js';
|
|
352
|
+
/**
|
|
353
|
+
* Initialize the extension and return a reactive channel.
|
|
354
|
+
*
|
|
355
|
+
* Sends `rool:ready` to the host, waits for the handshake, and returns
|
|
356
|
+
* a reactive channel with $state properties (interactions, objectIds)
|
|
357
|
+
* and reactive primitives (object(), watch()).
|
|
358
|
+
*/
|
|
359
|
+
export async function initExtension(timeout) {
|
|
360
|
+
const bridge = await initBridge(timeout);
|
|
361
|
+
return new ReactiveChannelImpl(bridge);
|
|
362
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight types for extension-side code.
|
|
3
|
+
*
|
|
4
|
+
* These mirror the SDK types but are defined locally so that
|
|
5
|
+
* @rool-dev/extension has zero runtime dependencies for extensions.
|
|
6
|
+
*/
|
|
7
|
+
export interface RoolObject {
|
|
8
|
+
id: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface RoolObjectStat {
|
|
12
|
+
modifiedAt: number;
|
|
13
|
+
modifiedBy: string;
|
|
14
|
+
modifiedByName: string | null;
|
|
15
|
+
}
|
|
16
|
+
export type FieldType = {
|
|
17
|
+
kind: 'string';
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'number';
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'boolean';
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'array';
|
|
24
|
+
inner?: FieldType;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'maybe';
|
|
27
|
+
inner: FieldType;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'enum';
|
|
30
|
+
values: string[];
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'literal';
|
|
33
|
+
value: string | number | boolean;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'ref';
|
|
36
|
+
};
|
|
37
|
+
export interface FieldDef {
|
|
38
|
+
name: string;
|
|
39
|
+
type: FieldType;
|
|
40
|
+
}
|
|
41
|
+
export interface CollectionDef {
|
|
42
|
+
fields: FieldDef[];
|
|
43
|
+
}
|
|
44
|
+
export type SpaceSchema = Record<string, CollectionDef>;
|
|
45
|
+
export interface ToolCall {
|
|
46
|
+
name: string;
|
|
47
|
+
input: unknown;
|
|
48
|
+
result?: string;
|
|
49
|
+
}
|
|
50
|
+
export type InteractionStatus = 'pending' | 'streaming' | 'done' | 'error';
|
|
51
|
+
export interface Interaction {
|
|
52
|
+
id: string;
|
|
53
|
+
timestamp: number;
|
|
54
|
+
userId: string;
|
|
55
|
+
userName?: string | null;
|
|
56
|
+
operation: 'prompt' | 'createObject' | 'updateObject' | 'deleteObjects';
|
|
57
|
+
input: string;
|
|
58
|
+
output: string | null;
|
|
59
|
+
status: InteractionStatus;
|
|
60
|
+
ai: boolean;
|
|
61
|
+
modifiedObjectIds: string[];
|
|
62
|
+
toolCalls: ToolCall[];
|
|
63
|
+
attachments?: string[];
|
|
64
|
+
}
|
|
65
|
+
export type PromptEffort = 'QUICK' | 'STANDARD' | 'REASONING' | 'RESEARCH';
|
|
66
|
+
export interface PromptOptions {
|
|
67
|
+
objectIds?: string[];
|
|
68
|
+
responseSchema?: Record<string, unknown>;
|
|
69
|
+
effort?: PromptEffort;
|
|
70
|
+
ephemeral?: boolean;
|
|
71
|
+
readOnly?: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface FindObjectsOptions {
|
|
74
|
+
where?: Record<string, unknown>;
|
|
75
|
+
collection?: string;
|
|
76
|
+
prompt?: string;
|
|
77
|
+
limit?: number;
|
|
78
|
+
objectIds?: string[];
|
|
79
|
+
order?: 'asc' | 'desc';
|
|
80
|
+
ephemeral?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface CreateObjectOptions {
|
|
83
|
+
data: Record<string, unknown>;
|
|
84
|
+
ephemeral?: boolean;
|
|
85
|
+
}
|
|
86
|
+
export interface UpdateObjectOptions {
|
|
87
|
+
data?: Record<string, unknown>;
|
|
88
|
+
prompt?: string;
|
|
89
|
+
ephemeral?: boolean;
|
|
90
|
+
}
|
|
91
|
+
export type ChangeSource = 'local_user' | 'remote_user' | 'remote_agent' | 'system';
|
|
92
|
+
export type RoolUserRole = 'owner' | 'admin' | 'editor' | 'viewer';
|
|
93
|
+
export type LinkAccess = 'none' | 'viewer' | 'editor';
|
|
94
|
+
export interface ConversationInfo {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string | null;
|
|
97
|
+
systemInstruction: string | null;
|
|
98
|
+
createdAt: number;
|
|
99
|
+
createdBy: string;
|
|
100
|
+
interactionCount: number;
|
|
101
|
+
}
|
|
102
|
+
export interface ChannelEvents {
|
|
103
|
+
objectCreated: {
|
|
104
|
+
objectId: string;
|
|
105
|
+
object: RoolObject;
|
|
106
|
+
source: ChangeSource;
|
|
107
|
+
};
|
|
108
|
+
objectUpdated: {
|
|
109
|
+
objectId: string;
|
|
110
|
+
object: RoolObject;
|
|
111
|
+
source: ChangeSource;
|
|
112
|
+
};
|
|
113
|
+
objectDeleted: {
|
|
114
|
+
objectId: string;
|
|
115
|
+
source: ChangeSource;
|
|
116
|
+
};
|
|
117
|
+
metadataUpdated: {
|
|
118
|
+
metadata: Record<string, unknown>;
|
|
119
|
+
source: ChangeSource;
|
|
120
|
+
};
|
|
121
|
+
schemaUpdated: {
|
|
122
|
+
schema: SpaceSchema;
|
|
123
|
+
source: ChangeSource;
|
|
124
|
+
};
|
|
125
|
+
channelUpdated: {
|
|
126
|
+
channelId: string;
|
|
127
|
+
source: ChangeSource;
|
|
128
|
+
};
|
|
129
|
+
conversationUpdated: {
|
|
130
|
+
conversationId: string;
|
|
131
|
+
channelId: string;
|
|
132
|
+
source: ChangeSource;
|
|
133
|
+
};
|
|
134
|
+
reset: {
|
|
135
|
+
source: ChangeSource;
|
|
136
|
+
};
|
|
137
|
+
syncError: Error;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rool-dev/extension",
|
|
3
|
+
"version": "0.3.5",
|
|
4
|
+
"description": "Svelte-first extension SDK for Rool — reactive channel over iframe bridge",
|
|
5
|
+
"packageManager": "pnpm@10.17.1",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"svelte": "./dist/index.js",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"svelte": "./dist/index.js",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./host": {
|
|
18
|
+
"types": "./dist/host.d.ts",
|
|
19
|
+
"default": "./dist/host.js"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"rool-extension": "./dist/cli/index.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "svelte-package -i src -o dist && chmod +x dist/cli/index.js && vite build -c build/vite.config.js",
|
|
31
|
+
"build:host-shell": "vite build -c build/vite.config.js",
|
|
32
|
+
"dev": "svelte-package -i src -o dist --watch",
|
|
33
|
+
"typecheck": "svelte-check --tsconfig ./tsconfig.json",
|
|
34
|
+
"clean": "rm -rf dist"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://docs.rool.dev",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/rool-dev/rool-js.git",
|
|
43
|
+
"directory": "packages/extension"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"rool",
|
|
47
|
+
"extension",
|
|
48
|
+
"svelte",
|
|
49
|
+
"iframe",
|
|
50
|
+
"sandbox",
|
|
51
|
+
"postmessage"
|
|
52
|
+
],
|
|
53
|
+
"author": {
|
|
54
|
+
"name": "Rool Limited",
|
|
55
|
+
"email": "info@rool.dev",
|
|
56
|
+
"url": "https://rool.dev"
|
|
57
|
+
},
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"svelte": "^5.0.0"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@rool-dev/sdk": "workspace:*",
|
|
64
|
+
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
65
|
+
"@tailwindcss/vite": "^4.2.2",
|
|
66
|
+
"archiver": "^7.0.1",
|
|
67
|
+
"tailwindcss": "^4.2.2",
|
|
68
|
+
"vite": "^8.0.0"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@sveltejs/package": "^2.5.7",
|
|
72
|
+
"@types/archiver": "^7.0.0",
|
|
73
|
+
"@types/node": "^25.5.0",
|
|
74
|
+
"gridstack": "^12.4.2",
|
|
75
|
+
"svelte": "^5.54.0",
|
|
76
|
+
"svelte-check": "^4.4.5",
|
|
77
|
+
"typescript": "^5.9.3"
|
|
78
|
+
}
|
|
79
|
+
}
|