@rool-dev/app 0.3.0

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.
Files changed (59) hide show
  1. package/README.md +306 -0
  2. package/dist/cli/dev.d.ts +10 -0
  3. package/dist/cli/dev.d.ts.map +1 -0
  4. package/dist/cli/dev.js +241 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +22 -0
  8. package/dist/cli/init.d.ts +7 -0
  9. package/dist/cli/init.d.ts.map +1 -0
  10. package/dist/cli/init.js +108 -0
  11. package/dist/cli/publish.d.ts +9 -0
  12. package/dist/cli/publish.d.ts.map +1 -0
  13. package/dist/cli/publish.js +213 -0
  14. package/dist/cli/vite-utils.d.ts +22 -0
  15. package/dist/cli/vite-utils.d.ts.map +1 -0
  16. package/dist/cli/vite-utils.js +96 -0
  17. package/dist/client.d.ts +79 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +235 -0
  20. package/dist/dev/AppGrid.svelte +246 -0
  21. package/dist/dev/AppGrid.svelte.d.ts +14 -0
  22. package/dist/dev/AppGrid.svelte.d.ts.map +1 -0
  23. package/dist/dev/DevHostController.d.ts +86 -0
  24. package/dist/dev/DevHostController.d.ts.map +1 -0
  25. package/dist/dev/DevHostController.js +395 -0
  26. package/dist/dev/HostShell.svelte +110 -0
  27. package/dist/dev/HostShell.svelte.d.ts +11 -0
  28. package/dist/dev/HostShell.svelte.d.ts.map +1 -0
  29. package/dist/dev/Sidebar.svelte +223 -0
  30. package/dist/dev/Sidebar.svelte.d.ts +19 -0
  31. package/dist/dev/Sidebar.svelte.d.ts.map +1 -0
  32. package/dist/dev/TabBar.svelte +83 -0
  33. package/dist/dev/TabBar.svelte.d.ts +14 -0
  34. package/dist/dev/TabBar.svelte.d.ts.map +1 -0
  35. package/dist/dev/app.css +1 -0
  36. package/dist/dev/host-shell.d.ts +8 -0
  37. package/dist/dev/host-shell.d.ts.map +1 -0
  38. package/dist/dev/host-shell.js +14807 -0
  39. package/dist/dev/host-shell.js.map +1 -0
  40. package/dist/dev/vite-env.d.ts +4 -0
  41. package/dist/host.d.ts +54 -0
  42. package/dist/host.d.ts.map +1 -0
  43. package/dist/host.js +171 -0
  44. package/dist/index.d.ts +10 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +8 -0
  47. package/dist/manifest.d.ts +35 -0
  48. package/dist/manifest.d.ts.map +1 -0
  49. package/dist/manifest.js +10 -0
  50. package/dist/protocol.d.ts +46 -0
  51. package/dist/protocol.d.ts.map +1 -0
  52. package/dist/protocol.js +14 -0
  53. package/dist/reactive.svelte.d.ts +100 -0
  54. package/dist/reactive.svelte.d.ts.map +1 -0
  55. package/dist/reactive.svelte.js +267 -0
  56. package/dist/types.d.ts +119 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +7 -0
  59. package/package.json +78 -0
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Reactive Svelte wrapper around AppChannel (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 directly.
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
+ const where = this.#options.where;
72
+ if (!where)
73
+ return true;
74
+ for (const [key, value] of Object.entries(where)) {
75
+ if (object[key] !== value)
76
+ return false;
77
+ }
78
+ return true;
79
+ }
80
+ async refresh() {
81
+ this.loading = true;
82
+ try {
83
+ const { objects } = await this.#channel.findObjects({
84
+ where: this.#options.where,
85
+ limit: this.#options.limit,
86
+ order: this.#options.order,
87
+ ephemeral: true,
88
+ });
89
+ this.objects = objects;
90
+ this.#currentIds = new Set(objects.map((o) => o.id));
91
+ }
92
+ finally {
93
+ this.loading = false;
94
+ }
95
+ }
96
+ close() {
97
+ for (const unsub of this.#unsubscribers)
98
+ unsub();
99
+ this.#unsubscribers.length = 0;
100
+ }
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // ReactiveObject
104
+ // ---------------------------------------------------------------------------
105
+ class ReactiveObjectImpl {
106
+ #channel;
107
+ #objectId;
108
+ #unsubscribers = [];
109
+ data = $state(undefined);
110
+ loading = $state(true);
111
+ constructor(channel, objectId) {
112
+ this.#channel = channel;
113
+ this.#objectId = objectId;
114
+ this.#setup();
115
+ }
116
+ #setup() {
117
+ this.refresh();
118
+ const onObjectUpdated = ({ objectId, object }) => {
119
+ if (objectId === this.#objectId)
120
+ this.data = object;
121
+ };
122
+ this.#channel.on('objectUpdated', onObjectUpdated);
123
+ this.#unsubscribers.push(() => this.#channel.off('objectUpdated', onObjectUpdated));
124
+ const onObjectCreated = ({ object }) => {
125
+ if (object.id === this.#objectId)
126
+ this.data = object;
127
+ };
128
+ this.#channel.on('objectCreated', onObjectCreated);
129
+ this.#unsubscribers.push(() => this.#channel.off('objectCreated', onObjectCreated));
130
+ const onObjectDeleted = ({ objectId }) => {
131
+ if (objectId === this.#objectId)
132
+ this.data = undefined;
133
+ };
134
+ this.#channel.on('objectDeleted', onObjectDeleted);
135
+ this.#unsubscribers.push(() => this.#channel.off('objectDeleted', onObjectDeleted));
136
+ const onReset = () => this.refresh();
137
+ this.#channel.on('reset', onReset);
138
+ this.#unsubscribers.push(() => this.#channel.off('reset', onReset));
139
+ }
140
+ async refresh() {
141
+ this.loading = true;
142
+ try {
143
+ this.data = await this.#channel.getObject(this.#objectId);
144
+ }
145
+ finally {
146
+ this.loading = false;
147
+ }
148
+ }
149
+ close() {
150
+ for (const unsub of this.#unsubscribers)
151
+ unsub();
152
+ this.#unsubscribers.length = 0;
153
+ }
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // ReactiveAppChannel
157
+ // ---------------------------------------------------------------------------
158
+ class ReactiveAppChannelImpl {
159
+ #channel;
160
+ #closed = false;
161
+ // Reactive state
162
+ interactions = $state([]);
163
+ objectIds = $state([]);
164
+ #unsubscribers = [];
165
+ constructor(channel) {
166
+ this.#channel = channel;
167
+ // Load initial data
168
+ channel.getInteractions().then((list) => { this.interactions = list; });
169
+ channel.getObjectIds().then((ids) => { this.objectIds = ids; });
170
+ // Subscribe to channel updates → refresh interactions
171
+ const onChannelUpdated = () => {
172
+ channel.getInteractions().then((list) => { this.interactions = list; });
173
+ };
174
+ channel.on('channelUpdated', onChannelUpdated);
175
+ this.#unsubscribers.push(() => channel.off('channelUpdated', onChannelUpdated));
176
+ // Subscribe to object events → refresh objectIds
177
+ const refreshObjectIds = () => {
178
+ channel.getObjectIds().then((ids) => { this.objectIds = ids; });
179
+ };
180
+ channel.on('objectCreated', refreshObjectIds);
181
+ this.#unsubscribers.push(() => channel.off('objectCreated', refreshObjectIds));
182
+ channel.on('objectDeleted', refreshObjectIds);
183
+ this.#unsubscribers.push(() => channel.off('objectDeleted', refreshObjectIds));
184
+ // Full resets
185
+ const onReset = () => {
186
+ channel.getInteractions().then((list) => { this.interactions = list; });
187
+ channel.getObjectIds().then((ids) => { this.objectIds = ids; });
188
+ };
189
+ channel.on('reset', onReset);
190
+ this.#unsubscribers.push(() => channel.off('reset', onReset));
191
+ }
192
+ // Proxied properties
193
+ get channelId() { return this.#channel.channelId; }
194
+ get spaceId() { return this.#channel.spaceId; }
195
+ get spaceName() { return this.#channel.spaceName; }
196
+ get role() { return this.#channel.role; }
197
+ get linkAccess() { return this.#channel.linkAccess; }
198
+ get userId() { return this.#channel.userId; }
199
+ get isReadOnly() { return this.#channel.isReadOnly; }
200
+ // Object operations
201
+ getObject(objectId) { return this.#channel.getObject(objectId); }
202
+ stat(objectId) { return this.#channel.stat(objectId); }
203
+ findObjects(options) { return this.#channel.findObjects(options); }
204
+ getObjectIds(options) { return this.#channel.getObjectIds(options); }
205
+ createObject(options) { return this.#channel.createObject(options); }
206
+ updateObject(objectId, options) { return this.#channel.updateObject(objectId, options); }
207
+ deleteObjects(objectIds) { return this.#channel.deleteObjects(objectIds); }
208
+ // AI
209
+ prompt(text, options) { return this.#channel.prompt(text, options); }
210
+ // Undo/redo
211
+ checkpoint(label) { return this.#channel.checkpoint(label); }
212
+ canUndo() { return this.#channel.canUndo(); }
213
+ canRedo() { return this.#channel.canRedo(); }
214
+ undo() { return this.#channel.undo(); }
215
+ redo() { return this.#channel.redo(); }
216
+ clearHistory() { return this.#channel.clearHistory(); }
217
+ // Metadata
218
+ setMetadata(key, value) { return this.#channel.setMetadata(key, value); }
219
+ getMetadata(key) { return this.#channel.getMetadata(key); }
220
+ getAllMetadata() { return this.#channel.getAllMetadata(); }
221
+ // History
222
+ getInteractions() { return this.#channel.getInteractions(); }
223
+ getSystemInstruction() { return this.#channel.getSystemInstruction(); }
224
+ setSystemInstruction(instruction) { return this.#channel.setSystemInstruction(instruction); }
225
+ // Schema
226
+ getSchema() { return this.#channel.getSchema(); }
227
+ createCollection(name, fields) { return this.#channel.createCollection(name, fields); }
228
+ alterCollection(name, fields) { return this.#channel.alterCollection(name, fields); }
229
+ dropCollection(name) { return this.#channel.dropCollection(name); }
230
+ // Events
231
+ on(...args) { return this.#channel.on(...args); }
232
+ off(...args) { return this.#channel.off(...args); }
233
+ // Reactive primitives
234
+ object(objectId) {
235
+ if (this.#closed)
236
+ throw new Error('Cannot create reactive object: channel is closed');
237
+ return new ReactiveObjectImpl(this.#channel, objectId);
238
+ }
239
+ watch(options) {
240
+ if (this.#closed)
241
+ throw new Error('Cannot create reactive watch: channel is closed');
242
+ return new ReactiveWatchImpl(this.#channel, options);
243
+ }
244
+ // Cleanup
245
+ destroy() {
246
+ this.#closed = true;
247
+ for (const unsub of this.#unsubscribers)
248
+ unsub();
249
+ this.#unsubscribers.length = 0;
250
+ this.#channel.destroy();
251
+ }
252
+ }
253
+ // ---------------------------------------------------------------------------
254
+ // initApp (reactive version)
255
+ // ---------------------------------------------------------------------------
256
+ import { initApp as initBridge } from './client.js';
257
+ /**
258
+ * Initialize the app and return a reactive channel.
259
+ *
260
+ * Sends `rool:ready` to the host, waits for the handshake, and returns
261
+ * a reactive channel with $state properties (interactions, objectIds)
262
+ * and reactive primitives (object(), watch()).
263
+ */
264
+ export async function initApp(timeout) {
265
+ const bridge = await initBridge(timeout);
266
+ return new ReactiveAppChannelImpl(bridge);
267
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Lightweight types for app-side code.
3
+ *
4
+ * These mirror the SDK types but are defined locally so that
5
+ * @rool-dev/app has zero runtime dependencies for apps.
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 interface Interaction {
51
+ id: string;
52
+ timestamp: number;
53
+ userId: string;
54
+ userName?: string | null;
55
+ operation: 'prompt' | 'createObject' | 'updateObject' | 'deleteObjects';
56
+ input: string;
57
+ output: string | null;
58
+ ai: boolean;
59
+ modifiedObjectIds: string[];
60
+ toolCalls: ToolCall[];
61
+ attachments?: string[];
62
+ }
63
+ export type PromptEffort = 'QUICK' | 'STANDARD' | 'REASONING' | 'RESEARCH';
64
+ export interface PromptOptions {
65
+ objectIds?: string[];
66
+ responseSchema?: Record<string, unknown>;
67
+ effort?: PromptEffort;
68
+ ephemeral?: boolean;
69
+ readOnly?: boolean;
70
+ }
71
+ export interface FindObjectsOptions {
72
+ where?: Record<string, unknown>;
73
+ prompt?: string;
74
+ limit?: number;
75
+ objectIds?: string[];
76
+ order?: 'asc' | 'desc';
77
+ ephemeral?: boolean;
78
+ }
79
+ export interface CreateObjectOptions {
80
+ data: Record<string, unknown>;
81
+ ephemeral?: boolean;
82
+ }
83
+ export interface UpdateObjectOptions {
84
+ data?: Record<string, unknown>;
85
+ prompt?: string;
86
+ ephemeral?: boolean;
87
+ }
88
+ export type ChangeSource = 'local_user' | 'remote_user' | 'remote_agent' | 'system';
89
+ export type RoolUserRole = 'owner' | 'admin' | 'editor' | 'viewer';
90
+ export type LinkAccess = 'none' | 'viewer' | 'editor';
91
+ export interface AppChannelEvents {
92
+ objectCreated: {
93
+ objectId: string;
94
+ object: RoolObject;
95
+ source: ChangeSource;
96
+ };
97
+ objectUpdated: {
98
+ objectId: string;
99
+ object: RoolObject;
100
+ source: ChangeSource;
101
+ };
102
+ objectDeleted: {
103
+ objectId: string;
104
+ source: ChangeSource;
105
+ };
106
+ metadataUpdated: {
107
+ metadata: Record<string, unknown>;
108
+ source: ChangeSource;
109
+ };
110
+ channelUpdated: {
111
+ channelId: string;
112
+ source: ChangeSource;
113
+ };
114
+ reset: {
115
+ source: ChangeSource;
116
+ };
117
+ syncError: Error;
118
+ }
119
+ //# 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
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Lightweight types for app-side code.
3
+ *
4
+ * These mirror the SDK types but are defined locally so that
5
+ * @rool-dev/app has zero runtime dependencies for apps.
6
+ */
7
+ export {};
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@rool-dev/app",
3
+ "version": "0.3.0",
4
+ "description": "Svelte-first app 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
+ },
22
+ "bin": {
23
+ "rool-app": "./dist/cli/index.js"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "scripts": {
29
+ "build": "svelte-package -i src -o dist && chmod +x dist/cli/index.js && vite build -c build/vite.config.js",
30
+ "build:host-shell": "vite build -c build/vite.config.js",
31
+ "dev": "svelte-package -i src -o dist --watch",
32
+ "typecheck": "svelte-check --tsconfig ./tsconfig.json",
33
+ "clean": "rm -rf dist"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "homepage": "https://docs.rool.dev",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/rool-dev/rool-js.git",
42
+ "directory": "packages/app"
43
+ },
44
+ "keywords": [
45
+ "rool",
46
+ "app",
47
+ "svelte",
48
+ "iframe",
49
+ "sandbox",
50
+ "postmessage"
51
+ ],
52
+ "author": {
53
+ "name": "Rool Limited",
54
+ "email": "info@rool.dev",
55
+ "url": "https://rool.dev"
56
+ },
57
+ "license": "MIT",
58
+ "peerDependencies": {
59
+ "svelte": "^5.0.0"
60
+ },
61
+ "dependencies": {
62
+ "@rool-dev/sdk": "workspace:*",
63
+ "@sveltejs/vite-plugin-svelte": "^5.1.1",
64
+ "@tailwindcss/vite": "^4.1.18",
65
+ "archiver": "^7.0.1",
66
+ "tailwindcss": "^4.1.18",
67
+ "vite": "^6.0.0"
68
+ },
69
+ "devDependencies": {
70
+ "@sveltejs/package": "^2.0.0",
71
+ "@types/archiver": "^7.0.0",
72
+ "@types/node": "^25.4.0",
73
+ "gridstack": "^12.4.2",
74
+ "svelte": "^5.0.0",
75
+ "svelte-check": "^4.0.0",
76
+ "typescript": "^5.9.3"
77
+ }
78
+ }