foundation-sdk 0.1.0 → 0.1.11

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 CHANGED
@@ -1,4 +1,4 @@
1
- # foundation-iframe-sdk
1
+ # foundation-sdk
2
2
 
3
3
  SDK for building applications that embed within the Foundation container.
4
4
 
@@ -7,13 +7,21 @@ SDK for building applications that embed within the Foundation container.
7
7
  ## Installation
8
8
 
9
9
  ```bash
10
- npm install foundation-iframe-sdk
10
+ npm install foundation-sdk
11
+ ```
12
+
13
+ Vue is an optional peer dependency - only required if using the `/vue` entry point:
14
+
15
+ ```bash
16
+ npm install foundation-sdk vue
11
17
  ```
12
18
 
13
19
  ## Quick Start
14
20
 
21
+ ### Vanilla TypeScript/JavaScript
22
+
15
23
  ```typescript
16
- import { createFoundationClient } from 'foundation-iframe-sdk'
24
+ import { createFoundationClient } from 'foundation-sdk'
17
25
 
18
26
  const sdk = createFoundationClient()
19
27
 
@@ -30,6 +38,26 @@ const { items } = await sdk.db.list('projects', { limit: 10 })
30
38
  await sdk.ui.toast('Hello from embedded app!', 'success')
31
39
  ```
32
40
 
41
+ ### Vue 3
42
+
43
+ ```typescript
44
+ import { useFoundation } from 'foundation-sdk/vue'
45
+
46
+ // In your component setup
47
+ const { isReady, user, isDark, db, ui } = useFoundation()
48
+
49
+ // Reactive state is automatically updated
50
+ watch(isReady, (ready) => {
51
+ if (ready) {
52
+ console.log('SDK ready, user:', user.value)
53
+ }
54
+ })
55
+
56
+ // Use services directly
57
+ const { items } = await db.list('projects', { limit: 10 })
58
+ await ui.toast('Hello!', 'success')
59
+ ```
60
+
33
61
  ## API Reference
34
62
 
35
63
  ### Initialization
@@ -48,6 +76,19 @@ if (sdk.isReady) {
48
76
 
49
77
  // Wait for ready
50
78
  await sdk.ready
79
+
80
+ // Access available entity definitions
81
+ console.log(sdk.entities) // EntityDefinition[]
82
+ ```
83
+
84
+ #### `resetFoundationClient(): void`
85
+
86
+ Resets the singleton instance. Useful for testing or re-initialization.
87
+
88
+ ```typescript
89
+ import { resetFoundationClient } from 'foundation-sdk'
90
+
91
+ resetFoundationClient()
51
92
  ```
52
93
 
53
94
  ---
@@ -224,6 +265,8 @@ const unsubscribe = sdk.router.onChange((route) => {
224
265
  interface ThemeService {
225
266
  readonly isDark: boolean
226
267
  readonly mode: 'light' | 'dark' | 'system'
268
+ setTheme(mode: 'light' | 'dark' | 'system'): Promise<void>
269
+ toggle(): Promise<void>
227
270
  onChange(callback: (theme: Theme) => void): () => void
228
271
  }
229
272
  ```
@@ -236,6 +279,13 @@ if (sdk.theme.isDark) {
236
279
  // Apply dark styles
237
280
  }
238
281
 
282
+ // Set specific theme mode
283
+ await sdk.theme.setTheme('dark')
284
+ await sdk.theme.setTheme('system')
285
+
286
+ // Toggle between light/dark
287
+ await sdk.theme.toggle()
288
+
239
289
  // Subscribe to theme changes
240
290
  const unsubscribe = sdk.theme.onChange((theme) => {
241
291
  document.body.classList.toggle('dark', theme.isDark)
@@ -387,6 +437,96 @@ const unsubscribe = sdk.onEntityChange((event) => {
387
437
 
388
438
  ---
389
439
 
440
+ ## Vue Integration
441
+
442
+ The SDK provides a Vue 3 composable for reactive state management:
443
+
444
+ ```typescript
445
+ import { useFoundation } from 'foundation-sdk/vue'
446
+ ```
447
+
448
+ ### `useFoundation()`
449
+
450
+ Returns reactive state and direct service access:
451
+
452
+ ```typescript
453
+ interface UseFoundationReturn {
454
+ // Reactive state (readonly refs)
455
+ isReady: Ref<boolean>
456
+ user: ShallowRef<User | null>
457
+ isDark: Ref<boolean>
458
+ themeMode: Ref<'light' | 'dark' | 'system'>
459
+ routerPath: Ref<string>
460
+ routerQuery: ShallowRef<Record<string, string>>
461
+ routerHash: Ref<string>
462
+ entities: ShallowRef<EntityDefinition[]>
463
+
464
+ // Computed helpers
465
+ isAuthenticated: boolean
466
+ currentUser: User | null
467
+
468
+ // Direct service access
469
+ client: FoundationClient
470
+ auth: AuthService
471
+ ui: UIService
472
+ db: DbService
473
+ router: RouterService
474
+ config: ConfigService
475
+ files: FilesService
476
+ storage: StorageService
477
+ log: LogService
478
+ theme: ThemeService
479
+
480
+ // Theme control shortcuts
481
+ setTheme(mode: 'light' | 'dark' | 'system'): Promise<void>
482
+ toggleTheme(): Promise<void>
483
+
484
+ // Entity change subscription
485
+ onEntityChange(callback: (event: EntityChangeEvent) => void): () => void
486
+ }
487
+ ```
488
+
489
+ **Example:**
490
+
491
+ ```vue
492
+ <script setup lang="ts">
493
+ import { useFoundation } from 'foundation-sdk/vue'
494
+ import { watch } from 'vue'
495
+
496
+ const { isReady, user, isDark, db, ui, toggleTheme } = useFoundation()
497
+
498
+ // Reactive state updates automatically
499
+ watch(user, (newUser) => {
500
+ console.log('User changed:', newUser?.email)
501
+ })
502
+
503
+ // Theme reactivity
504
+ watch(isDark, (dark) => {
505
+ document.body.classList.toggle('dark-mode', dark)
506
+ })
507
+
508
+ async function loadProjects() {
509
+ const { items } = await db.list('projects', { limit: 10 })
510
+ return items
511
+ }
512
+
513
+ async function handleClick() {
514
+ await toggleTheme()
515
+ await ui.toast('Theme toggled!', 'success')
516
+ }
517
+ </script>
518
+
519
+ <template>
520
+ <div v-if="isReady">
521
+ <p>Welcome, {{ user?.name }}</p>
522
+ <button @click="handleClick">Toggle Theme</button>
523
+ </div>
524
+ <div v-else>Loading...</div>
525
+ </template>
526
+ ```
527
+
528
+ ---
529
+
390
530
  ## TypeScript
391
531
 
392
532
  Full TypeScript support with exported types:
@@ -397,12 +537,19 @@ import type {
397
537
  User,
398
538
  Theme,
399
539
  RouterState,
540
+ EntityDefinition,
400
541
  EntityChangeEvent,
401
542
  AuthService,
543
+ ThemeService,
544
+ RouterService,
402
545
  DbService,
403
546
  UIService,
404
- // ... more types
405
- } from 'foundation-iframe-sdk'
547
+ StorageService,
548
+ FilesService,
549
+ FileMetadata,
550
+ LogService,
551
+ ConfigService
552
+ } from 'foundation-sdk'
406
553
  ```
407
554
 
408
555
  ---
@@ -0,0 +1,4 @@
1
+ import { FoundationClient } from './types';
2
+ export declare function createFoundationClient(): FoundationClient;
3
+ export declare function resetFoundationClient(): void;
4
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAkBjB,MAAM,SAAS,CAAA;AAIhB,wBAAgB,sBAAsB,IAAI,gBAAgB,CAqQzD;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
package/dist/index.cjs CHANGED
@@ -196,6 +196,20 @@ function createFoundationClient() {
196
196
  };
197
197
  const filesService = {
198
198
  initiate: (options) => send("files", "initiate", options),
199
+ upload: async (options) => {
200
+ let fileData;
201
+ if (options.file instanceof ArrayBuffer) {
202
+ fileData = options.file;
203
+ } else {
204
+ fileData = await options.file.arrayBuffer();
205
+ }
206
+ return send("files", "upload", {
207
+ name: options.name,
208
+ contentType: options.contentType,
209
+ fileData,
210
+ sha256: options.sha256
211
+ });
212
+ },
199
213
  get: (fileId) => send("files", "get", { fileId }),
200
214
  delete: (fileId) => send("files", "delete", { fileId }),
201
215
  list: (options = {}) => send("files", "list", options)
@@ -227,6 +241,12 @@ function createFoundationClient() {
227
241
  },
228
242
  get: (key) => send("config", "get", { key })
229
243
  };
244
+ const stuffService = {
245
+ set: (key, namespace, value) => send("stuff", "set", { key, namespace, value }),
246
+ get: (key, namespace) => send("stuff", "get", { key, namespace }),
247
+ list: (key) => send("stuff", "list", { key }),
248
+ delete: (key, namespace) => send("stuff", "delete", { key, namespace })
249
+ };
230
250
  clientInstance = {
231
251
  get ready() {
232
252
  return readyPromise;
@@ -246,6 +266,7 @@ function createFoundationClient() {
246
266
  files: filesService,
247
267
  log: logService,
248
268
  config: configService,
269
+ stuff: stuffService,
249
270
  onEntityChange(callback) {
250
271
  entityListeners.push(callback);
251
272
  return () => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/client.ts"],"sourcesContent":["import type {\n FoundationClient,\n User,\n Theme,\n RouterState,\n EntityDefinition,\n EntityChangeEvent,\n SDKReadyPayload,\n SDKResponse,\n AuthService,\n ThemeService,\n RouterService,\n DbService,\n UIService,\n StorageService,\n FilesService,\n LogService,\n ConfigService\n} from './types'\n\nlet clientInstance: FoundationClient | null = null\n\nexport function createFoundationClient(): FoundationClient {\n if (clientInstance) {\n return clientInstance\n }\n\n let isReady = false\n let readyResolve: (() => void) | null = null\n let messageId = 0\n const pendingRequests = new Map<number, { resolve: (data: unknown) => void; reject: (error: Error) => void }>()\n\n let user: User | null = null\n let theme: Theme = { isDark: false, mode: 'system' }\n let router: RouterState = { path: '/', query: {}, hash: '' }\n let config: { features: Record<string, unknown>; app: { id?: string; name?: string; environment?: string } } = { features: {}, app: {} }\n let entities: EntityDefinition[] = []\n\n const themeListeners: Array<(theme: Theme) => void> = []\n const authListeners: Array<(user: User | null) => void> = []\n const routerListeners: Array<(route: RouterState) => void> = []\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const readyPromise = new Promise<void>((resolve) => {\n readyResolve = resolve\n })\n\n function send<T = unknown>(namespace: string, type: string, data: Record<string, unknown> = {}): Promise<T> {\n return new Promise((resolve, reject) => {\n const id = ++messageId\n pendingRequests.set(id, {\n resolve: resolve as (data: unknown) => void,\n reject\n })\n\n window.parent.postMessage({\n id,\n namespace,\n type: `${namespace}.${type}`,\n data\n }, '*')\n\n setTimeout(() => {\n if (pendingRequests.has(id)) {\n pendingRequests.delete(id)\n reject(new Error(`Request timeout: ${namespace}.${type}`))\n }\n }, 30000)\n })\n }\n\n function handleMessage(event: MessageEvent) {\n const message = event.data\n\n if (message?.type === 'SDK_READY') {\n const payload = message.data as SDKReadyPayload\n user = payload.user || null\n theme = payload.theme || { isDark: false, mode: 'system' }\n router = payload.router || { path: '/', query: {}, hash: '' }\n config = {\n features: payload.config?.features || {},\n app: payload.config?.app || {}\n }\n entities = payload.entities || []\n\n if (!isReady) {\n isReady = true\n readyResolve?.()\n }\n return\n }\n\n if (message?.type === 'THEME_CHANGED') {\n theme = message.data as Theme\n themeListeners.forEach(fn => {\n try { fn(theme) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'AUTH_CHANGED') {\n user = message.data?.user || null\n authListeners.forEach(fn => {\n try { fn(user) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ROUTER_CHANGED') {\n router = message.data as RouterState\n routerListeners.forEach(fn => {\n try { fn(router) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ENTITY_CHANGED') {\n const event = message.data as EntityChangeEvent\n entityListeners.forEach(fn => {\n try { fn(event) } catch { /* ignore */ }\n })\n return\n }\n\n if (typeof message?.id === 'number' && pendingRequests.has(message.id)) {\n const { resolve, reject } = pendingRequests.get(message.id)!\n pendingRequests.delete(message.id)\n\n const response = message as SDKResponse\n if (response.success) {\n resolve(response.data)\n } else {\n reject(new Error(response.error || 'Unknown error'))\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n\n const authService: AuthService = {\n get user() { return user },\n get isAuthenticated() { return !!user },\n getToken: () => send<string>('auth', 'getToken'),\n login: () => send<void>('auth', 'login'),\n logout: () => send<void>('auth', 'logout'),\n onChange(callback) {\n authListeners.push(callback)\n return () => {\n const idx = authListeners.indexOf(callback)\n if (idx > -1) authListeners.splice(idx, 1)\n }\n }\n }\n\n const themeService: ThemeService = {\n get isDark() { return theme.isDark },\n get mode() { return theme.mode },\n setTheme: (mode) => send<void>('ui', 'setTheme', { mode }),\n toggle: () => send<void>('ui', 'toggleTheme', {}),\n onChange(callback) {\n themeListeners.push(callback)\n return () => {\n const idx = themeListeners.indexOf(callback)\n if (idx > -1) themeListeners.splice(idx, 1)\n }\n }\n }\n\n const routerService: RouterService = {\n get path() { return router.path },\n get query() { return router.query },\n get hash() { return router.hash },\n push: (path, options = {}) => send<void>('router', 'push', { path, ...options }),\n replace: (path, options = {}) => send<void>('router', 'replace', { path, ...options }),\n setQuery: (params, options = {}) => send<void>('router', 'setQuery', { params, ...options }),\n onChange(callback) {\n routerListeners.push(callback)\n return () => {\n const idx = routerListeners.indexOf(callback)\n if (idx > -1) routerListeners.splice(idx, 1)\n }\n }\n }\n\n const dbService: DbService = {\n list: (entity, options = {}) => send('db', 'list', { entity, ...options }),\n get: (entity, id) => send('db', 'get', { entity, itemId: id }),\n create: (entity, item) => send('db', 'create', { entity, item }),\n update: (entity, id, updates) => send('db', 'update', { entity, itemId: id, updates }),\n delete: (entity, id) => send('db', 'delete', { entity, itemId: id })\n }\n\n const uiService: UIService = {\n toast: (message, type = 'info') => send('ui', 'toast', { message, toastType: type }),\n confirm: (message) => send('ui', 'confirm', { message }),\n loading: {\n show: (message) => send('ui', 'loading.show', { message }),\n hide: () => send('ui', 'loading.hide', {})\n },\n banner: {\n show: (message, options = {}) => send('ui', 'banner.show', { message, ...options }),\n hide: (bannerId) => send('ui', 'banner.hide', { bannerId })\n }\n }\n\n const storageService: StorageService = {\n upload: (options) => send('storage', 'upload', options),\n get: (fileId) => send('storage', 'get', { fileId }),\n delete: (fileId) => send('storage', 'delete', { fileId }),\n list: (options = {}) => send('storage', 'list', options)\n }\n\n const filesService: FilesService = {\n initiate: (options) => send('files', 'initiate', options),\n get: (fileId) => send('files', 'get', { fileId }),\n delete: (fileId) => send('files', 'delete', { fileId }),\n list: (options = {}) => send('files', 'list', options)\n }\n\n const logService: LogService = {\n info: (message, data) => { send('log', 'info', { message, data }).catch(() => {}) },\n warn: (message, data) => { send('log', 'warn', { message, data }).catch(() => {}) },\n error: (message, data) => { send('log', 'error', { message, data }).catch(() => {}) },\n event: (name, properties) => { send('log', 'event', { name, properties }).catch(() => {}) }\n }\n\n const configService: ConfigService = {\n get features() { return config.features },\n get app() { return config.app },\n get: (key) => send('config', 'get', { key })\n }\n\n clientInstance = {\n get ready() { return readyPromise },\n get isReady() { return isReady },\n\n auth: authService, // only logout - this is problematic - provides user and account\n theme: themeService, // only useful for themed tailwind projects - still useful anyway\n router: routerService, // once you're in app - external or container-ui level routing it just not very useful.\n db: dbService,\n ui: uiService,\n storage: storageService,\n files: filesService,\n log: logService,\n config: configService,\n\n onEntityChange(callback) {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n },\n\n get entities() { return entities }\n }\n\n return clientInstance\n}\n\nexport function resetFoundationClient(): void {\n clientInstance = null\n}\n"],"names":["event"],"mappings":";;AAoBA,IAAI,iBAA0C;AAEvC,SAAS,yBAA2C;AACzD,MAAI,gBAAgB;AAClB,WAAO;AAAA,EACT;AAEA,MAAI,UAAU;AACd,MAAI,eAAoC;AACxC,MAAI,YAAY;AAChB,QAAM,sCAAsB,IAAA;AAE5B,MAAI,OAAoB;AACxB,MAAI,QAAe,EAAE,QAAQ,OAAO,MAAM,SAAA;AAC1C,MAAI,SAAsB,EAAE,MAAM,KAAK,OAAO,CAAA,GAAI,MAAM,GAAA;AACxD,MAAI,SAA2G,EAAE,UAAU,CAAA,GAAI,KAAK,CAAA,EAAC;AACrI,MAAI,WAA+B,CAAA;AAEnC,QAAM,iBAAgD,CAAA;AACtD,QAAM,gBAAoD,CAAA;AAC1D,QAAM,kBAAuD,CAAA;AAC7D,QAAM,kBAA6D,CAAA;AAEnE,QAAM,eAAe,IAAI,QAAc,CAAC,YAAY;AAClD,mBAAe;AAAA,EACjB,CAAC;AAED,WAAS,KAAkB,WAAmB,MAAc,OAAgC,CAAA,GAAgB;AAC1G,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,KAAK,EAAE;AACb,sBAAgB,IAAI,IAAI;AAAA,QACtB;AAAA,QACA;AAAA,MAAA,CACD;AAED,aAAO,OAAO,YAAY;AAAA,QACxB;AAAA,QACA;AAAA,QACA,MAAM,GAAG,SAAS,IAAI,IAAI;AAAA,QAC1B;AAAA,MAAA,GACC,GAAG;AAEN,iBAAW,MAAM;AACf,YAAI,gBAAgB,IAAI,EAAE,GAAG;AAC3B,0BAAgB,OAAO,EAAE;AACzB,iBAAO,IAAI,MAAM,oBAAoB,SAAS,IAAI,IAAI,EAAE,CAAC;AAAA,QAC3D;AAAA,MACF,GAAG,GAAK;AAAA,IACV,CAAC;AAAA,EACH;AAEA,WAAS,cAAc,OAAqB;;AAC1C,UAAM,UAAU,MAAM;AAEtB,SAAI,mCAAS,UAAS,aAAa;AACjC,YAAM,UAAU,QAAQ;AACxB,aAAO,QAAQ,QAAQ;AACvB,cAAQ,QAAQ,SAAS,EAAE,QAAQ,OAAO,MAAM,SAAA;AAChD,eAAS,QAAQ,UAAU,EAAE,MAAM,KAAK,OAAO,CAAA,GAAI,MAAM,GAAA;AACzD,eAAS;AAAA,QACP,YAAU,aAAQ,WAAR,mBAAgB,aAAY,CAAA;AAAA,QACtC,OAAK,aAAQ,WAAR,mBAAgB,QAAO,CAAA;AAAA,MAAC;AAE/B,iBAAW,QAAQ,YAAY,CAAA;AAE/B,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV;AAAA,MACF;AACA;AAAA,IACF;AAEA,SAAI,mCAAS,UAAS,iBAAiB;AACrC,cAAQ,QAAQ;AAChB,qBAAe,QAAQ,CAAA,OAAM;AAC3B,YAAI;AAAE,aAAG,KAAK;AAAA,QAAE,QAAQ;AAAA,QAAe;AAAA,MACzC,CAAC;AACD;AAAA,IACF;AAEA,SAAI,mCAAS,UAAS,gBAAgB;AACpC,eAAO,aAAQ,SAAR,mBAAc,SAAQ;AAC7B,oBAAc,QAAQ,CAAA,OAAM;AAC1B,YAAI;AAAE,aAAG,IAAI;AAAA,QAAE,QAAQ;AAAA,QAAe;AAAA,MACxC,CAAC;AACD;AAAA,IACF;AAEA,SAAI,mCAAS,UAAS,kBAAkB;AACtC,eAAS,QAAQ;AACjB,sBAAgB,QAAQ,CAAA,OAAM;AAC5B,YAAI;AAAE,aAAG,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAe;AAAA,MAC1C,CAAC;AACD;AAAA,IACF;AAEA,SAAI,mCAAS,UAAS,kBAAkB;AACtC,YAAMA,SAAQ,QAAQ;AACtB,sBAAgB,QAAQ,CAAA,OAAM;AAC5B,YAAI;AAAE,aAAGA,MAAK;AAAA,QAAE,QAAQ;AAAA,QAAe;AAAA,MACzC,CAAC;AACD;AAAA,IACF;AAEA,QAAI,QAAO,mCAAS,QAAO,YAAY,gBAAgB,IAAI,QAAQ,EAAE,GAAG;AACtE,YAAM,EAAE,SAAS,OAAA,IAAW,gBAAgB,IAAI,QAAQ,EAAE;AAC1D,sBAAgB,OAAO,QAAQ,EAAE;AAEjC,YAAM,WAAW;AACjB,UAAI,SAAS,SAAS;AACpB,gBAAQ,SAAS,IAAI;AAAA,MACvB,OAAO;AACL,eAAO,IAAI,MAAM,SAAS,SAAS,eAAe,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,iBAAiB,WAAW,aAAa;AAEhD,QAAM,cAA2B;AAAA,IAC/B,IAAI,OAAO;AAAE,aAAO;AAAA,IAAK;AAAA,IACzB,IAAI,kBAAkB;AAAE,aAAO,CAAC,CAAC;AAAA,IAAK;AAAA,IACtC,UAAU,MAAM,KAAa,QAAQ,UAAU;AAAA,IAC/C,OAAO,MAAM,KAAW,QAAQ,OAAO;AAAA,IACvC,QAAQ,MAAM,KAAW,QAAQ,QAAQ;AAAA,IACzC,SAAS,UAAU;AACjB,oBAAc,KAAK,QAAQ;AAC3B,aAAO,MAAM;AACX,cAAM,MAAM,cAAc,QAAQ,QAAQ;AAC1C,YAAI,MAAM,GAAI,eAAc,OAAO,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EAAA;AAGF,QAAM,eAA6B;AAAA,IACjC,IAAI,SAAS;AAAE,aAAO,MAAM;AAAA,IAAO;AAAA,IACnC,IAAI,OAAO;AAAE,aAAO,MAAM;AAAA,IAAK;AAAA,IAC/B,UAAU,CAAC,SAAS,KAAW,MAAM,YAAY,EAAE,MAAM;AAAA,IACzD,QAAQ,MAAM,KAAW,MAAM,eAAe,CAAA,CAAE;AAAA,IAChD,SAAS,UAAU;AACjB,qBAAe,KAAK,QAAQ;AAC5B,aAAO,MAAM;AACX,cAAM,MAAM,eAAe,QAAQ,QAAQ;AAC3C,YAAI,MAAM,GAAI,gBAAe,OAAO,KAAK,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,EAAA;AAGF,QAAM,gBAA+B;AAAA,IACnC,IAAI,OAAO;AAAE,aAAO,OAAO;AAAA,IAAK;AAAA,IAChC,IAAI,QAAQ;AAAE,aAAO,OAAO;AAAA,IAAM;AAAA,IAClC,IAAI,OAAO;AAAE,aAAO,OAAO;AAAA,IAAK;AAAA,IAChC,MAAM,CAAC,MAAM,UAAU,OAAO,KAAW,UAAU,QAAQ,EAAE,MAAM,GAAG,SAAS;AAAA,IAC/E,SAAS,CAAC,MAAM,UAAU,OAAO,KAAW,UAAU,WAAW,EAAE,MAAM,GAAG,SAAS;AAAA,IACrF,UAAU,CAAC,QAAQ,UAAU,OAAO,KAAW,UAAU,YAAY,EAAE,QAAQ,GAAG,SAAS;AAAA,IAC3F,SAAS,UAAU;AACjB,sBAAgB,KAAK,QAAQ;AAC7B,aAAO,MAAM;AACX,cAAM,MAAM,gBAAgB,QAAQ,QAAQ;AAC5C,YAAI,MAAM,GAAI,iBAAgB,OAAO,KAAK,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EAAA;AAGF,QAAM,YAAuB;AAAA,IAC3B,MAAM,CAAC,QAAQ,UAAU,OAAO,KAAK,MAAM,QAAQ,EAAE,QAAQ,GAAG,SAAS;AAAA,IACzE,KAAK,CAAC,QAAQ,OAAO,KAAK,MAAM,OAAO,EAAE,QAAQ,QAAQ,IAAI;AAAA,IAC7D,QAAQ,CAAC,QAAQ,SAAS,KAAK,MAAM,UAAU,EAAE,QAAQ,MAAM;AAAA,IAC/D,QAAQ,CAAC,QAAQ,IAAI,YAAY,KAAK,MAAM,UAAU,EAAE,QAAQ,QAAQ,IAAI,SAAS;AAAA,IACrF,QAAQ,CAAC,QAAQ,OAAO,KAAK,MAAM,UAAU,EAAE,QAAQ,QAAQ,GAAA,CAAI;AAAA,EAAA;AAGrE,QAAM,YAAuB;AAAA,IAC3B,OAAO,CAAC,SAAS,OAAO,WAAW,KAAK,MAAM,SAAS,EAAE,SAAS,WAAW,KAAA,CAAM;AAAA,IACnF,SAAS,CAAC,YAAY,KAAK,MAAM,WAAW,EAAE,SAAS;AAAA,IACvD,SAAS;AAAA,MACP,MAAM,CAAC,YAAY,KAAK,MAAM,gBAAgB,EAAE,SAAS;AAAA,MACzD,MAAM,MAAM,KAAK,MAAM,gBAAgB,CAAA,CAAE;AAAA,IAAA;AAAA,IAE3C,QAAQ;AAAA,MACN,MAAM,CAAC,SAAS,UAAU,OAAO,KAAK,MAAM,eAAe,EAAE,SAAS,GAAG,SAAS;AAAA,MAClF,MAAM,CAAC,aAAa,KAAK,MAAM,eAAe,EAAE,UAAU;AAAA,IAAA;AAAA,EAC5D;AAGF,QAAM,iBAAiC;AAAA,IACrC,QAAQ,CAAC,YAAY,KAAK,WAAW,UAAU,OAAO;AAAA,IACtD,KAAK,CAAC,WAAW,KAAK,WAAW,OAAO,EAAE,QAAQ;AAAA,IAClD,QAAQ,CAAC,WAAW,KAAK,WAAW,UAAU,EAAE,QAAQ;AAAA,IACxD,MAAM,CAAC,UAAU,CAAA,MAAO,KAAK,WAAW,QAAQ,OAAO;AAAA,EAAA;AAGzD,QAAM,eAA6B;AAAA,IACjC,UAAU,CAAC,YAAY,KAAK,SAAS,YAAY,OAAO;AAAA,IACxD,KAAK,CAAC,WAAW,KAAK,SAAS,OAAO,EAAE,QAAQ;AAAA,IAChD,QAAQ,CAAC,WAAW,KAAK,SAAS,UAAU,EAAE,QAAQ;AAAA,IACtD,MAAM,CAAC,UAAU,CAAA,MAAO,KAAK,SAAS,QAAQ,OAAO;AAAA,EAAA;AAGvD,QAAM,aAAyB;AAAA,IAC7B,MAAM,CAAC,SAAS,SAAS;AAAE,WAAK,OAAO,QAAQ,EAAE,SAAS,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAAE;AAAA,IAClF,MAAM,CAAC,SAAS,SAAS;AAAE,WAAK,OAAO,QAAQ,EAAE,SAAS,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAAE;AAAA,IAClF,OAAO,CAAC,SAAS,SAAS;AAAE,WAAK,OAAO,SAAS,EAAE,SAAS,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAAE;AAAA,IACpF,OAAO,CAAC,MAAM,eAAe;AAAE,WAAK,OAAO,SAAS,EAAE,MAAM,YAAY,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAAE;AAAA,EAAA;AAG5F,QAAM,gBAA+B;AAAA,IACnC,IAAI,WAAW;AAAE,aAAO,OAAO;AAAA,IAAS;AAAA,IACxC,IAAI,MAAM;AAAE,aAAO,OAAO;AAAA,IAAI;AAAA,IAC9B,KAAK,CAAC,QAAQ,KAAK,UAAU,OAAO,EAAE,KAAK;AAAA,EAAA;AAG7C,mBAAiB;AAAA,IACf,IAAI,QAAQ;AAAE,aAAO;AAAA,IAAa;AAAA,IAClC,IAAI,UAAU;AAAE,aAAO;AAAA,IAAQ;AAAA,IAE/B,MAAM;AAAA;AAAA,IACN,OAAO;AAAA;AAAA,IACP,QAAQ;AAAA;AAAA,IACR,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,IAER,eAAe,UAAU;AACvB,sBAAgB,KAAK,QAAQ;AAC7B,aAAO,MAAM;AACX,cAAM,MAAM,gBAAgB,QAAQ,QAAQ;AAC5C,YAAI,MAAM,GAAI,iBAAgB,OAAO,KAAK,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,IAEA,IAAI,WAAW;AAAE,aAAO;AAAA,IAAS;AAAA,EAAA;AAGnC,SAAO;AACT;AAEO,SAAS,wBAA8B;AAC5C,mBAAiB;AACnB;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/client.ts"],"sourcesContent":["import type {\n FoundationClient,\n User,\n Theme,\n RouterState,\n EntityDefinition,\n EntityChangeEvent,\n SDKReadyPayload,\n SDKResponse,\n AuthService,\n ThemeService,\n RouterService,\n DbService,\n UIService,\n StorageService,\n FilesService,\n LogService,\n ConfigService,\n StuffService\n} from './types'\n\nlet clientInstance: FoundationClient | null = null\n\nexport function createFoundationClient(): FoundationClient {\n if (clientInstance) {\n return clientInstance\n }\n\n let isReady = false\n let readyResolve: (() => void) | null = null\n let messageId = 0\n const pendingRequests = new Map<number, { resolve: (data: unknown) => void; reject: (error: Error) => void }>()\n\n let user: User | null = null\n let theme: Theme = { isDark: false, mode: 'system' }\n let router: RouterState = { path: '/', query: {}, hash: '' }\n let config: { features: Record<string, unknown>; app: { id?: string; name?: string; environment?: string } } = { features: {}, app: {} }\n let entities: EntityDefinition[] = []\n\n const themeListeners: Array<(theme: Theme) => void> = []\n const authListeners: Array<(user: User | null) => void> = []\n const routerListeners: Array<(route: RouterState) => void> = []\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const readyPromise = new Promise<void>((resolve) => {\n readyResolve = resolve\n })\n\n function send<T = unknown>(namespace: string, type: string, data: Record<string, unknown> = {}): Promise<T> {\n return new Promise((resolve, reject) => {\n const id = ++messageId\n pendingRequests.set(id, {\n resolve: resolve as (data: unknown) => void,\n reject\n })\n\n window.parent.postMessage({\n id,\n namespace,\n type: `${namespace}.${type}`,\n data\n }, '*')\n\n setTimeout(() => {\n if (pendingRequests.has(id)) {\n pendingRequests.delete(id)\n reject(new Error(`Request timeout: ${namespace}.${type}`))\n }\n }, 30000)\n })\n }\n\n function handleMessage(event: MessageEvent) {\n const message = event.data\n\n if (message?.type === 'SDK_READY') {\n const payload = message.data as SDKReadyPayload\n user = payload.user || null\n theme = payload.theme || { isDark: false, mode: 'system' }\n router = payload.router || { path: '/', query: {}, hash: '' }\n config = {\n features: payload.config?.features || {},\n app: payload.config?.app || {}\n }\n entities = payload.entities || []\n\n if (!isReady) {\n isReady = true\n readyResolve?.()\n }\n return\n }\n\n if (message?.type === 'THEME_CHANGED') {\n theme = message.data as Theme\n themeListeners.forEach(fn => {\n try { fn(theme) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'AUTH_CHANGED') {\n user = message.data?.user || null\n authListeners.forEach(fn => {\n try { fn(user) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ROUTER_CHANGED') {\n router = message.data as RouterState\n routerListeners.forEach(fn => {\n try { fn(router) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ENTITY_CHANGED') {\n const event = message.data as EntityChangeEvent\n entityListeners.forEach(fn => {\n try { fn(event) } catch { /* ignore */ }\n })\n return\n }\n\n if (typeof message?.id === 'number' && pendingRequests.has(message.id)) {\n const { resolve, reject } = pendingRequests.get(message.id)!\n pendingRequests.delete(message.id)\n\n const response = message as SDKResponse\n if (response.success) {\n resolve(response.data)\n } else {\n reject(new Error(response.error || 'Unknown error'))\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n\n const authService: AuthService = {\n get user() { return user },\n get isAuthenticated() { return !!user },\n getToken: () => send<string>('auth', 'getToken'),\n login: () => send<void>('auth', 'login'),\n logout: () => send<void>('auth', 'logout'),\n onChange(callback) {\n authListeners.push(callback)\n return () => {\n const idx = authListeners.indexOf(callback)\n if (idx > -1) authListeners.splice(idx, 1)\n }\n }\n }\n\n const themeService: ThemeService = {\n get isDark() { return theme.isDark },\n get mode() { return theme.mode },\n setTheme: (mode) => send<void>('ui', 'setTheme', { mode }),\n toggle: () => send<void>('ui', 'toggleTheme', {}),\n onChange(callback) {\n themeListeners.push(callback)\n return () => {\n const idx = themeListeners.indexOf(callback)\n if (idx > -1) themeListeners.splice(idx, 1)\n }\n }\n }\n\n const routerService: RouterService = {\n get path() { return router.path },\n get query() { return router.query },\n get hash() { return router.hash },\n push: (path, options = {}) => send<void>('router', 'push', { path, ...options }),\n replace: (path, options = {}) => send<void>('router', 'replace', { path, ...options }),\n setQuery: (params, options = {}) => send<void>('router', 'setQuery', { params, ...options }),\n onChange(callback) {\n routerListeners.push(callback)\n return () => {\n const idx = routerListeners.indexOf(callback)\n if (idx > -1) routerListeners.splice(idx, 1)\n }\n }\n }\n\n const dbService: DbService = {\n list: (entity, options = {}) => send('db', 'list', { entity, ...options }),\n get: (entity, id) => send('db', 'get', { entity, itemId: id }),\n create: (entity, item) => send('db', 'create', { entity, item }),\n update: (entity, id, updates) => send('db', 'update', { entity, itemId: id, updates }),\n delete: (entity, id) => send('db', 'delete', { entity, itemId: id })\n }\n\n const uiService: UIService = {\n toast: (message, type = 'info') => send('ui', 'toast', { message, toastType: type }),\n confirm: (message) => send('ui', 'confirm', { message }),\n loading: {\n show: (message) => send('ui', 'loading.show', { message }),\n hide: () => send('ui', 'loading.hide', {})\n },\n banner: {\n show: (message, options = {}) => send('ui', 'banner.show', { message, ...options }),\n hide: (bannerId) => send('ui', 'banner.hide', { bannerId })\n }\n }\n\n const storageService: StorageService = {\n upload: (options) => send('storage', 'upload', options),\n get: (fileId) => send('storage', 'get', { fileId }),\n delete: (fileId) => send('storage', 'delete', { fileId }),\n list: (options = {}) => send('storage', 'list', options)\n }\n\n const filesService: FilesService = {\n initiate: (options) => send('files', 'initiate', options),\n upload: async (options) => {\n // Convert File/Blob to ArrayBuffer for postMessage transfer\n let fileData: ArrayBuffer\n if (options.file instanceof ArrayBuffer) {\n fileData = options.file\n } else {\n // File or Blob - use arrayBuffer()\n fileData = await options.file.arrayBuffer()\n }\n\n return send('files', 'upload', {\n name: options.name,\n contentType: options.contentType,\n fileData,\n sha256: options.sha256\n })\n },\n get: (fileId) => send('files', 'get', { fileId }),\n delete: (fileId) => send('files', 'delete', { fileId }),\n list: (options = {}) => send('files', 'list', options)\n }\n\n const logService: LogService = {\n info: (message, data) => { send('log', 'info', { message, data }).catch(() => {}) },\n warn: (message, data) => { send('log', 'warn', { message, data }).catch(() => {}) },\n error: (message, data) => { send('log', 'error', { message, data }).catch(() => {}) },\n event: (name, properties) => { send('log', 'event', { name, properties }).catch(() => {}) }\n }\n\n const configService: ConfigService = {\n get features() { return config.features },\n get app() { return config.app },\n get: (key) => send('config', 'get', { key })\n }\n\n const stuffService: StuffService = {\n set: (key, namespace, value) => send('stuff', 'set', { key, namespace, value }),\n get: (key, namespace) => send('stuff', 'get', { key, namespace }),\n list: (key) => send('stuff', 'list', { key }),\n delete: (key, namespace) => send('stuff', 'delete', { key, namespace })\n }\n\n clientInstance = {\n get ready() { return readyPromise },\n get isReady() { return isReady },\n\n auth: authService, // only logout - this is problematic - provides user and account\n theme: themeService, // only useful for themed tailwind projects - still useful anyway\n router: routerService, // once you're in app - external or container-ui level routing it just not very useful.\n db: dbService,\n ui: uiService,\n storage: storageService,\n files: filesService,\n log: logService,\n config: configService,\n stuff: stuffService,\n\n onEntityChange(callback) {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n },\n\n get entities() { return entities }\n }\n\n return clientInstance\n}\n\nexport function resetFoundationClient(): void {\n clientInstance = null\n}\n"],"names":["event"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,202 +1,3 @@
1
- export declare interface AuthService {
2
- readonly user: User | null;
3
- readonly isAuthenticated: boolean;
4
- getToken(): Promise<string>;
5
- login(): Promise<void>;
6
- logout(): Promise<void>;
7
- onChange(callback: (user: User | null) => void): () => void;
8
- }
9
-
10
- export declare interface ConfigService {
11
- readonly features: Record<string, unknown>;
12
- readonly app: {
13
- id?: string;
14
- name?: string;
15
- environment?: string;
16
- };
17
- get(key: string): Promise<unknown>;
18
- }
19
-
20
- export declare function createFoundationClient(): FoundationClient;
21
-
22
- export declare interface DbService {
23
- list<T = unknown>(entity: string, options?: {
24
- filters?: Record<string, unknown>;
25
- limit?: number;
26
- cursor?: string;
27
- orderBy?: string;
28
- orderDir?: 'asc' | 'desc';
29
- }): Promise<{
30
- items: T[];
31
- nextCursor?: string;
32
- }>;
33
- get<T = unknown>(entity: string, id: string): Promise<T>;
34
- create<T = unknown>(entity: string, data: Partial<T>): Promise<T>;
35
- update<T = unknown>(entity: string, id: string, updates: Partial<T>): Promise<T>;
36
- delete(entity: string, id: string): Promise<void>;
37
- }
38
-
39
- export declare interface EntityChangeEvent {
40
- changeType: string;
41
- entityId?: string;
42
- id?: string;
43
- namespace?: string;
44
- timestamp?: number;
45
- }
46
-
47
- export declare interface EntityDefinition {
48
- name: string;
49
- schema?: Record<string, unknown>;
50
- methods?: string[];
51
- }
52
-
53
- export declare interface FileMetadata {
54
- id: string;
55
- name: string;
56
- type: string;
57
- size: number;
58
- url: string;
59
- folder?: string;
60
- metadata?: Record<string, unknown>;
61
- createdAt: string;
62
- }
63
-
64
- export declare interface FilesService {
65
- initiate(options: {
66
- name: string;
67
- contentType: string;
68
- contentLength: number;
69
- metadata?: Record<string, unknown>;
70
- }): Promise<{
71
- id: string;
72
- name: string;
73
- signedUrl: string;
74
- signedData: Record<string, string>;
75
- }>;
76
- get(fileId: string): Promise<FileMetadata>;
77
- delete(fileId: string): Promise<void>;
78
- list(options?: {
79
- limit?: number;
80
- cursor?: string;
81
- }): Promise<{
82
- items: FileMetadata[];
83
- nextCursor?: string;
84
- }>;
85
- }
86
-
87
- export declare interface FoundationClient {
88
- readonly ready: Promise<void>;
89
- readonly isReady: boolean;
90
- auth: AuthService;
91
- theme: ThemeService;
92
- router: RouterService;
93
- db: DbService;
94
- ui: UIService;
95
- storage: StorageService;
96
- files: FilesService;
97
- log: LogService;
98
- config: ConfigService;
99
- onEntityChange(callback: (event: EntityChangeEvent) => void): () => void;
100
- readonly entities: EntityDefinition[];
101
- }
102
-
103
- export declare interface LogService {
104
- info(message: string, data?: Record<string, unknown>): void;
105
- warn(message: string, data?: Record<string, unknown>): void;
106
- error(message: string, data?: Record<string, unknown>): void;
107
- event(name: string, properties?: Record<string, unknown>): void;
108
- }
109
-
110
- export declare function resetFoundationClient(): void;
111
-
112
- export declare interface RouterService {
113
- readonly path: string;
114
- readonly query: Record<string, string>;
115
- readonly hash: string;
116
- push(path: string, options?: {
117
- query?: Record<string, string>;
118
- hash?: string;
119
- }): Promise<void>;
120
- replace(path: string, options?: {
121
- query?: Record<string, string>;
122
- hash?: string;
123
- }): Promise<void>;
124
- setQuery(params: Record<string, string>, options?: {
125
- replace?: boolean;
126
- }): Promise<void>;
127
- onChange(callback: (route: RouterState) => void): () => void;
128
- }
129
-
130
- export declare interface RouterState {
131
- path: string;
132
- query: Record<string, string>;
133
- hash: string;
134
- }
135
-
136
- export declare interface StorageService {
137
- upload(options: {
138
- name: string;
139
- type: string;
140
- size: number;
141
- data: string;
142
- folder?: string;
143
- metadata?: Record<string, unknown>;
144
- }): Promise<{
145
- id: string;
146
- url: string;
147
- name: string;
148
- }>;
149
- get(fileId: string): Promise<FileMetadata>;
150
- delete(fileId: string): Promise<void>;
151
- list(options?: {
152
- folder?: string;
153
- limit?: number;
154
- cursor?: string;
155
- }): Promise<{
156
- items: FileMetadata[];
157
- nextCursor?: string;
158
- }>;
159
- }
160
-
161
- export declare interface Theme {
162
- isDark: boolean;
163
- mode: 'light' | 'dark' | 'system';
164
- }
165
-
166
- export declare interface ThemeService {
167
- readonly isDark: boolean;
168
- readonly mode: 'light' | 'dark' | 'system';
169
- setTheme(mode: 'light' | 'dark' | 'system'): Promise<void>;
170
- toggle(): Promise<void>;
171
- onChange(callback: (theme: Theme) => void): () => void;
172
- }
173
-
174
- export declare interface UIService {
175
- toast(message: string, type?: 'success' | 'error' | 'warn' | 'info'): Promise<void>;
176
- confirm(message: string): Promise<{
177
- confirmed: boolean;
178
- }>;
179
- loading: {
180
- show(message?: string): Promise<void>;
181
- hide(): Promise<void>;
182
- };
183
- banner: {
184
- show(message: string, options?: {
185
- type?: 'info' | 'warning' | 'error' | 'success';
186
- dismissible?: boolean;
187
- }): Promise<{
188
- bannerId: string;
189
- }>;
190
- hide(bannerId: string): Promise<void>;
191
- };
192
- }
193
-
194
- export declare interface User {
195
- id: string;
196
- email: string;
197
- name?: string;
198
- picture?: string;
199
- [key: string]: unknown;
200
- }
201
-
202
- export { }
1
+ export { createFoundationClient, resetFoundationClient } from './client';
2
+ export type { FoundationClient, User, Theme, RouterState, EntityDefinition, EntityChangeEvent, AuthService, ThemeService, RouterService, DbService, UIService, StorageService, FilesService, FileMetadata, LogService, ConfigService, StuffService, StuffItem } from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAExE,YAAY,EACV,gBAAgB,EAChB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,SAAS,EACT,SAAS,EACT,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,EACZ,SAAS,EACV,MAAM,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -194,6 +194,20 @@ function createFoundationClient() {
194
194
  };
195
195
  const filesService = {
196
196
  initiate: (options) => send("files", "initiate", options),
197
+ upload: async (options) => {
198
+ let fileData;
199
+ if (options.file instanceof ArrayBuffer) {
200
+ fileData = options.file;
201
+ } else {
202
+ fileData = await options.file.arrayBuffer();
203
+ }
204
+ return send("files", "upload", {
205
+ name: options.name,
206
+ contentType: options.contentType,
207
+ fileData,
208
+ sha256: options.sha256
209
+ });
210
+ },
197
211
  get: (fileId) => send("files", "get", { fileId }),
198
212
  delete: (fileId) => send("files", "delete", { fileId }),
199
213
  list: (options = {}) => send("files", "list", options)
@@ -225,6 +239,12 @@ function createFoundationClient() {
225
239
  },
226
240
  get: (key) => send("config", "get", { key })
227
241
  };
242
+ const stuffService = {
243
+ set: (key, namespace, value) => send("stuff", "set", { key, namespace, value }),
244
+ get: (key, namespace) => send("stuff", "get", { key, namespace }),
245
+ list: (key) => send("stuff", "list", { key }),
246
+ delete: (key, namespace) => send("stuff", "delete", { key, namespace })
247
+ };
228
248
  clientInstance = {
229
249
  get ready() {
230
250
  return readyPromise;
@@ -244,6 +264,7 @@ function createFoundationClient() {
244
264
  files: filesService,
245
265
  log: logService,
246
266
  config: configService,
267
+ stuff: stuffService,
247
268
  onEntityChange(callback) {
248
269
  entityListeners.push(callback);
249
270
  return () => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/client.ts"],"sourcesContent":["import type {\n FoundationClient,\n User,\n Theme,\n RouterState,\n EntityDefinition,\n EntityChangeEvent,\n SDKReadyPayload,\n SDKResponse,\n AuthService,\n ThemeService,\n RouterService,\n DbService,\n UIService,\n StorageService,\n FilesService,\n LogService,\n ConfigService\n} from './types'\n\nlet clientInstance: FoundationClient | null = null\n\nexport function createFoundationClient(): FoundationClient {\n if (clientInstance) {\n return clientInstance\n }\n\n let isReady = false\n let readyResolve: (() => void) | null = null\n let messageId = 0\n const pendingRequests = new Map<number, { resolve: (data: unknown) => void; reject: (error: Error) => void }>()\n\n let user: User | null = null\n let theme: Theme = { isDark: false, mode: 'system' }\n let router: RouterState = { path: '/', query: {}, hash: '' }\n let config: { features: Record<string, unknown>; app: { id?: string; name?: string; environment?: string } } = { features: {}, app: {} }\n let entities: EntityDefinition[] = []\n\n const themeListeners: Array<(theme: Theme) => void> = []\n const authListeners: Array<(user: User | null) => void> = []\n const routerListeners: Array<(route: RouterState) => void> = []\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const readyPromise = new Promise<void>((resolve) => {\n readyResolve = resolve\n })\n\n function send<T = unknown>(namespace: string, type: string, data: Record<string, unknown> = {}): Promise<T> {\n return new Promise((resolve, reject) => {\n const id = ++messageId\n pendingRequests.set(id, {\n resolve: resolve as (data: unknown) => void,\n reject\n })\n\n window.parent.postMessage({\n id,\n namespace,\n type: `${namespace}.${type}`,\n data\n }, '*')\n\n setTimeout(() => {\n if (pendingRequests.has(id)) {\n pendingRequests.delete(id)\n reject(new Error(`Request timeout: ${namespace}.${type}`))\n }\n }, 30000)\n })\n }\n\n function handleMessage(event: MessageEvent) {\n const message = event.data\n\n if (message?.type === 'SDK_READY') {\n const payload = message.data as SDKReadyPayload\n user = payload.user || null\n theme = payload.theme || { isDark: false, mode: 'system' }\n router = payload.router || { path: '/', query: {}, hash: '' }\n config = {\n features: payload.config?.features || {},\n app: payload.config?.app || {}\n }\n entities = payload.entities || []\n\n if (!isReady) {\n isReady = true\n readyResolve?.()\n }\n return\n }\n\n if (message?.type === 'THEME_CHANGED') {\n theme = message.data as Theme\n themeListeners.forEach(fn => {\n try { fn(theme) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'AUTH_CHANGED') {\n user = message.data?.user || null\n authListeners.forEach(fn => {\n try { fn(user) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ROUTER_CHANGED') {\n router = message.data as RouterState\n routerListeners.forEach(fn => {\n try { fn(router) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ENTITY_CHANGED') {\n const event = message.data as EntityChangeEvent\n entityListeners.forEach(fn => {\n try { fn(event) } catch { /* ignore */ }\n })\n return\n }\n\n if (typeof message?.id === 'number' && pendingRequests.has(message.id)) {\n const { resolve, reject } = pendingRequests.get(message.id)!\n pendingRequests.delete(message.id)\n\n const response = message as SDKResponse\n if (response.success) {\n resolve(response.data)\n } else {\n reject(new Error(response.error || 'Unknown error'))\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n\n const authService: AuthService = {\n get user() { return user },\n get isAuthenticated() { return !!user },\n getToken: () => send<string>('auth', 'getToken'),\n login: () => send<void>('auth', 'login'),\n logout: () => send<void>('auth', 'logout'),\n onChange(callback) {\n authListeners.push(callback)\n return () => {\n const idx = authListeners.indexOf(callback)\n if (idx > -1) authListeners.splice(idx, 1)\n }\n }\n }\n\n const themeService: ThemeService = {\n get isDark() { return theme.isDark },\n get mode() { return theme.mode },\n setTheme: (mode) => send<void>('ui', 'setTheme', { mode }),\n toggle: () => send<void>('ui', 'toggleTheme', {}),\n onChange(callback) {\n themeListeners.push(callback)\n return () => {\n const idx = themeListeners.indexOf(callback)\n if (idx > -1) themeListeners.splice(idx, 1)\n }\n }\n }\n\n const routerService: RouterService = {\n get path() { return router.path },\n get query() { return router.query },\n get hash() { return router.hash },\n push: (path, options = {}) => send<void>('router', 'push', { path, ...options }),\n replace: (path, options = {}) => send<void>('router', 'replace', { path, ...options }),\n setQuery: (params, options = {}) => send<void>('router', 'setQuery', { params, ...options }),\n onChange(callback) {\n routerListeners.push(callback)\n return () => {\n const idx = routerListeners.indexOf(callback)\n if (idx > -1) routerListeners.splice(idx, 1)\n }\n }\n }\n\n const dbService: DbService = {\n list: (entity, options = {}) => send('db', 'list', { entity, ...options }),\n get: (entity, id) => send('db', 'get', { entity, itemId: id }),\n create: (entity, item) => send('db', 'create', { entity, item }),\n update: (entity, id, updates) => send('db', 'update', { entity, itemId: id, updates }),\n delete: (entity, id) => send('db', 'delete', { entity, itemId: id })\n }\n\n const uiService: UIService = {\n toast: (message, type = 'info') => send('ui', 'toast', { message, toastType: type }),\n confirm: (message) => send('ui', 'confirm', { message }),\n loading: {\n show: (message) => send('ui', 'loading.show', { message }),\n hide: () => send('ui', 'loading.hide', {})\n },\n banner: {\n show: (message, options = {}) => send('ui', 'banner.show', { message, ...options }),\n hide: (bannerId) => send('ui', 'banner.hide', { bannerId })\n }\n }\n\n const storageService: StorageService = {\n upload: (options) => send('storage', 'upload', options),\n get: (fileId) => send('storage', 'get', { fileId }),\n delete: (fileId) => send('storage', 'delete', { fileId }),\n list: (options = {}) => send('storage', 'list', options)\n }\n\n const filesService: FilesService = {\n initiate: (options) => send('files', 'initiate', options),\n get: (fileId) => send('files', 'get', { fileId }),\n delete: (fileId) => send('files', 'delete', { fileId }),\n list: (options = {}) => send('files', 'list', options)\n }\n\n const logService: LogService = {\n info: (message, data) => { send('log', 'info', { message, data }).catch(() => {}) },\n warn: (message, data) => { send('log', 'warn', { message, data }).catch(() => {}) },\n error: (message, data) => { send('log', 'error', { message, data }).catch(() => {}) },\n event: (name, properties) => { send('log', 'event', { name, properties }).catch(() => {}) }\n }\n\n const configService: ConfigService = {\n get features() { return config.features },\n get app() { return config.app },\n get: (key) => send('config', 'get', { key })\n }\n\n clientInstance = {\n get ready() { return readyPromise },\n get isReady() { return isReady },\n\n auth: authService, // only logout - this is problematic - provides user and account\n theme: themeService, // only useful for themed tailwind projects - still useful anyway\n router: routerService, // once you're in app - external or container-ui level routing it just not very useful.\n db: dbService,\n ui: uiService,\n storage: storageService,\n files: filesService,\n log: logService,\n config: configService,\n\n onEntityChange(callback) {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n },\n\n get entities() { return entities }\n }\n\n return clientInstance\n}\n\nexport function resetFoundationClient(): void {\n clientInstance = null\n}\n"],"names":["event"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/client.ts"],"sourcesContent":["import type {\n FoundationClient,\n User,\n Theme,\n RouterState,\n EntityDefinition,\n EntityChangeEvent,\n SDKReadyPayload,\n SDKResponse,\n AuthService,\n ThemeService,\n RouterService,\n DbService,\n UIService,\n StorageService,\n FilesService,\n LogService,\n ConfigService,\n StuffService\n} from './types'\n\nlet clientInstance: FoundationClient | null = null\n\nexport function createFoundationClient(): FoundationClient {\n if (clientInstance) {\n return clientInstance\n }\n\n let isReady = false\n let readyResolve: (() => void) | null = null\n let messageId = 0\n const pendingRequests = new Map<number, { resolve: (data: unknown) => void; reject: (error: Error) => void }>()\n\n let user: User | null = null\n let theme: Theme = { isDark: false, mode: 'system' }\n let router: RouterState = { path: '/', query: {}, hash: '' }\n let config: { features: Record<string, unknown>; app: { id?: string; name?: string; environment?: string } } = { features: {}, app: {} }\n let entities: EntityDefinition[] = []\n\n const themeListeners: Array<(theme: Theme) => void> = []\n const authListeners: Array<(user: User | null) => void> = []\n const routerListeners: Array<(route: RouterState) => void> = []\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const readyPromise = new Promise<void>((resolve) => {\n readyResolve = resolve\n })\n\n function send<T = unknown>(namespace: string, type: string, data: Record<string, unknown> = {}): Promise<T> {\n return new Promise((resolve, reject) => {\n const id = ++messageId\n pendingRequests.set(id, {\n resolve: resolve as (data: unknown) => void,\n reject\n })\n\n window.parent.postMessage({\n id,\n namespace,\n type: `${namespace}.${type}`,\n data\n }, '*')\n\n setTimeout(() => {\n if (pendingRequests.has(id)) {\n pendingRequests.delete(id)\n reject(new Error(`Request timeout: ${namespace}.${type}`))\n }\n }, 30000)\n })\n }\n\n function handleMessage(event: MessageEvent) {\n const message = event.data\n\n if (message?.type === 'SDK_READY') {\n const payload = message.data as SDKReadyPayload\n user = payload.user || null\n theme = payload.theme || { isDark: false, mode: 'system' }\n router = payload.router || { path: '/', query: {}, hash: '' }\n config = {\n features: payload.config?.features || {},\n app: payload.config?.app || {}\n }\n entities = payload.entities || []\n\n if (!isReady) {\n isReady = true\n readyResolve?.()\n }\n return\n }\n\n if (message?.type === 'THEME_CHANGED') {\n theme = message.data as Theme\n themeListeners.forEach(fn => {\n try { fn(theme) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'AUTH_CHANGED') {\n user = message.data?.user || null\n authListeners.forEach(fn => {\n try { fn(user) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ROUTER_CHANGED') {\n router = message.data as RouterState\n routerListeners.forEach(fn => {\n try { fn(router) } catch { /* ignore */ }\n })\n return\n }\n\n if (message?.type === 'ENTITY_CHANGED') {\n const event = message.data as EntityChangeEvent\n entityListeners.forEach(fn => {\n try { fn(event) } catch { /* ignore */ }\n })\n return\n }\n\n if (typeof message?.id === 'number' && pendingRequests.has(message.id)) {\n const { resolve, reject } = pendingRequests.get(message.id)!\n pendingRequests.delete(message.id)\n\n const response = message as SDKResponse\n if (response.success) {\n resolve(response.data)\n } else {\n reject(new Error(response.error || 'Unknown error'))\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n\n const authService: AuthService = {\n get user() { return user },\n get isAuthenticated() { return !!user },\n getToken: () => send<string>('auth', 'getToken'),\n login: () => send<void>('auth', 'login'),\n logout: () => send<void>('auth', 'logout'),\n onChange(callback) {\n authListeners.push(callback)\n return () => {\n const idx = authListeners.indexOf(callback)\n if (idx > -1) authListeners.splice(idx, 1)\n }\n }\n }\n\n const themeService: ThemeService = {\n get isDark() { return theme.isDark },\n get mode() { return theme.mode },\n setTheme: (mode) => send<void>('ui', 'setTheme', { mode }),\n toggle: () => send<void>('ui', 'toggleTheme', {}),\n onChange(callback) {\n themeListeners.push(callback)\n return () => {\n const idx = themeListeners.indexOf(callback)\n if (idx > -1) themeListeners.splice(idx, 1)\n }\n }\n }\n\n const routerService: RouterService = {\n get path() { return router.path },\n get query() { return router.query },\n get hash() { return router.hash },\n push: (path, options = {}) => send<void>('router', 'push', { path, ...options }),\n replace: (path, options = {}) => send<void>('router', 'replace', { path, ...options }),\n setQuery: (params, options = {}) => send<void>('router', 'setQuery', { params, ...options }),\n onChange(callback) {\n routerListeners.push(callback)\n return () => {\n const idx = routerListeners.indexOf(callback)\n if (idx > -1) routerListeners.splice(idx, 1)\n }\n }\n }\n\n const dbService: DbService = {\n list: (entity, options = {}) => send('db', 'list', { entity, ...options }),\n get: (entity, id) => send('db', 'get', { entity, itemId: id }),\n create: (entity, item) => send('db', 'create', { entity, item }),\n update: (entity, id, updates) => send('db', 'update', { entity, itemId: id, updates }),\n delete: (entity, id) => send('db', 'delete', { entity, itemId: id })\n }\n\n const uiService: UIService = {\n toast: (message, type = 'info') => send('ui', 'toast', { message, toastType: type }),\n confirm: (message) => send('ui', 'confirm', { message }),\n loading: {\n show: (message) => send('ui', 'loading.show', { message }),\n hide: () => send('ui', 'loading.hide', {})\n },\n banner: {\n show: (message, options = {}) => send('ui', 'banner.show', { message, ...options }),\n hide: (bannerId) => send('ui', 'banner.hide', { bannerId })\n }\n }\n\n const storageService: StorageService = {\n upload: (options) => send('storage', 'upload', options),\n get: (fileId) => send('storage', 'get', { fileId }),\n delete: (fileId) => send('storage', 'delete', { fileId }),\n list: (options = {}) => send('storage', 'list', options)\n }\n\n const filesService: FilesService = {\n initiate: (options) => send('files', 'initiate', options),\n upload: async (options) => {\n // Convert File/Blob to ArrayBuffer for postMessage transfer\n let fileData: ArrayBuffer\n if (options.file instanceof ArrayBuffer) {\n fileData = options.file\n } else {\n // File or Blob - use arrayBuffer()\n fileData = await options.file.arrayBuffer()\n }\n\n return send('files', 'upload', {\n name: options.name,\n contentType: options.contentType,\n fileData,\n sha256: options.sha256\n })\n },\n get: (fileId) => send('files', 'get', { fileId }),\n delete: (fileId) => send('files', 'delete', { fileId }),\n list: (options = {}) => send('files', 'list', options)\n }\n\n const logService: LogService = {\n info: (message, data) => { send('log', 'info', { message, data }).catch(() => {}) },\n warn: (message, data) => { send('log', 'warn', { message, data }).catch(() => {}) },\n error: (message, data) => { send('log', 'error', { message, data }).catch(() => {}) },\n event: (name, properties) => { send('log', 'event', { name, properties }).catch(() => {}) }\n }\n\n const configService: ConfigService = {\n get features() { return config.features },\n get app() { return config.app },\n get: (key) => send('config', 'get', { key })\n }\n\n const stuffService: StuffService = {\n set: (key, namespace, value) => send('stuff', 'set', { key, namespace, value }),\n get: (key, namespace) => send('stuff', 'get', { key, namespace }),\n list: (key) => send('stuff', 'list', { key }),\n delete: (key, namespace) => send('stuff', 'delete', { key, namespace })\n }\n\n clientInstance = {\n get ready() { return readyPromise },\n get isReady() { return isReady },\n\n auth: authService, // only logout - this is problematic - provides user and account\n theme: themeService, // only useful for themed tailwind projects - still useful anyway\n router: routerService, // once you're in app - external or container-ui level routing it just not very useful.\n db: dbService,\n ui: uiService,\n storage: storageService,\n files: filesService,\n log: logService,\n config: configService,\n stuff: stuffService,\n\n onEntityChange(callback) {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n },\n\n get entities() { return entities }\n }\n\n return clientInstance\n}\n\nexport function resetFoundationClient(): void {\n clientInstance = null\n}\n"],"names":["event"],"mappings":"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"}
@@ -0,0 +1,238 @@
1
+ export interface User {
2
+ id: string;
3
+ email: string;
4
+ name?: string;
5
+ picture?: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface Theme {
9
+ isDark: boolean;
10
+ mode: 'light' | 'dark' | 'system';
11
+ }
12
+ export interface RouterState {
13
+ path: string;
14
+ query: Record<string, string>;
15
+ hash: string;
16
+ }
17
+ export interface EntityDefinition {
18
+ name: string;
19
+ schema?: Record<string, unknown>;
20
+ methods?: string[];
21
+ }
22
+ export interface AuthService {
23
+ readonly user: User | null;
24
+ readonly isAuthenticated: boolean;
25
+ getToken(): Promise<string>;
26
+ login(): Promise<void>;
27
+ logout(): Promise<void>;
28
+ onChange(callback: (user: User | null) => void): () => void;
29
+ }
30
+ export interface ThemeService {
31
+ readonly isDark: boolean;
32
+ readonly mode: 'light' | 'dark' | 'system';
33
+ setTheme(mode: 'light' | 'dark' | 'system'): Promise<void>;
34
+ toggle(): Promise<void>;
35
+ onChange(callback: (theme: Theme) => void): () => void;
36
+ }
37
+ export interface RouterService {
38
+ readonly path: string;
39
+ readonly query: Record<string, string>;
40
+ readonly hash: string;
41
+ push(path: string, options?: {
42
+ query?: Record<string, string>;
43
+ hash?: string;
44
+ }): Promise<void>;
45
+ replace(path: string, options?: {
46
+ query?: Record<string, string>;
47
+ hash?: string;
48
+ }): Promise<void>;
49
+ setQuery(params: Record<string, string>, options?: {
50
+ replace?: boolean;
51
+ }): Promise<void>;
52
+ onChange(callback: (route: RouterState) => void): () => void;
53
+ }
54
+ export interface DbService {
55
+ list<T = unknown>(entity: string, options?: {
56
+ filters?: Record<string, unknown>;
57
+ limit?: number;
58
+ cursor?: string;
59
+ orderBy?: string;
60
+ orderDir?: 'asc' | 'desc';
61
+ }): Promise<{
62
+ items: T[];
63
+ nextCursor?: string;
64
+ }>;
65
+ get<T = unknown>(entity: string, id: string): Promise<T>;
66
+ create<T = unknown>(entity: string, data: Partial<T>): Promise<T>;
67
+ update<T = unknown>(entity: string, id: string, updates: Partial<T>): Promise<T>;
68
+ delete(entity: string, id: string): Promise<void>;
69
+ }
70
+ export interface UIService {
71
+ toast(message: string, type?: 'success' | 'error' | 'warn' | 'info'): Promise<void>;
72
+ confirm(message: string): Promise<{
73
+ confirmed: boolean;
74
+ }>;
75
+ loading: {
76
+ show(message?: string): Promise<void>;
77
+ hide(): Promise<void>;
78
+ };
79
+ banner: {
80
+ show(message: string, options?: {
81
+ type?: 'info' | 'warning' | 'error' | 'success';
82
+ dismissible?: boolean;
83
+ }): Promise<{
84
+ bannerId: string;
85
+ }>;
86
+ hide(bannerId: string): Promise<void>;
87
+ };
88
+ }
89
+ export interface StorageService {
90
+ upload(options: {
91
+ name: string;
92
+ type: string;
93
+ size: number;
94
+ data: string;
95
+ folder?: string;
96
+ metadata?: Record<string, unknown>;
97
+ }): Promise<{
98
+ id: string;
99
+ url: string;
100
+ name: string;
101
+ }>;
102
+ get(fileId: string): Promise<FileMetadata>;
103
+ delete(fileId: string): Promise<void>;
104
+ list(options?: {
105
+ folder?: string;
106
+ limit?: number;
107
+ cursor?: string;
108
+ }): Promise<{
109
+ items: FileMetadata[];
110
+ nextCursor?: string;
111
+ }>;
112
+ }
113
+ export interface FilesService {
114
+ initiate(options: {
115
+ name: string;
116
+ contentType: string;
117
+ contentLength: number;
118
+ metadata?: Record<string, unknown>;
119
+ sha256: string;
120
+ }): Promise<{
121
+ id: string;
122
+ name: string;
123
+ signedUrl: string;
124
+ signedData: Record<string, string>;
125
+ }>;
126
+ /**
127
+ * Upload a file through the parent container (avoids CORS issues with S3).
128
+ * The parent handles both getting the presigned URL and uploading to S3.
129
+ */
130
+ upload(options: {
131
+ name: string;
132
+ contentType: string;
133
+ file: ArrayBuffer | Blob | File;
134
+ sha256: string;
135
+ }): Promise<{
136
+ id: string;
137
+ name: string;
138
+ status: string;
139
+ s3UploadComplete: boolean;
140
+ }>;
141
+ get(fileId: string): Promise<FileMetadata>;
142
+ delete(fileId: string): Promise<void>;
143
+ list(options?: {
144
+ limit?: number;
145
+ cursor?: string;
146
+ }): Promise<{
147
+ items: FileMetadata[];
148
+ nextCursor?: string;
149
+ }>;
150
+ }
151
+ export interface FileMetadata {
152
+ id: string;
153
+ name: string;
154
+ type: string;
155
+ size: number;
156
+ url: string;
157
+ folder?: string;
158
+ metadata?: Record<string, unknown>;
159
+ createdAt: string;
160
+ }
161
+ export interface LogService {
162
+ info(message: string, data?: Record<string, unknown>): void;
163
+ warn(message: string, data?: Record<string, unknown>): void;
164
+ error(message: string, data?: Record<string, unknown>): void;
165
+ event(name: string, properties?: Record<string, unknown>): void;
166
+ }
167
+ export interface StuffItem<T = unknown> {
168
+ key: string;
169
+ namespace: string;
170
+ value: T;
171
+ type: string;
172
+ expires: number;
173
+ }
174
+ export interface StuffService {
175
+ set<T = unknown>(key: string, namespace: string, value: T): Promise<StuffItem<T>>;
176
+ get<T = unknown>(key: string, namespace: string): Promise<StuffItem<T>>;
177
+ list<T = unknown>(key: string): Promise<StuffItem<T>[]>;
178
+ delete(key: string, namespace: string): Promise<void>;
179
+ }
180
+ export interface ConfigService {
181
+ readonly features: Record<string, unknown>;
182
+ readonly app: {
183
+ id?: string;
184
+ name?: string;
185
+ environment?: string;
186
+ };
187
+ get(key: string): Promise<unknown>;
188
+ }
189
+ export interface EntityChangeEvent {
190
+ changeType: string;
191
+ entityId?: string;
192
+ id?: string;
193
+ namespace?: string;
194
+ timestamp?: number;
195
+ }
196
+ export interface FoundationClient {
197
+ readonly ready: Promise<void>;
198
+ readonly isReady: boolean;
199
+ auth: AuthService;
200
+ theme: ThemeService;
201
+ router: RouterService;
202
+ db: DbService;
203
+ ui: UIService;
204
+ storage: StorageService;
205
+ files: FilesService;
206
+ log: LogService;
207
+ config: ConfigService;
208
+ stuff: StuffService;
209
+ onEntityChange(callback: (event: EntityChangeEvent) => void): () => void;
210
+ readonly entities: EntityDefinition[];
211
+ }
212
+ export interface SDKReadyPayload {
213
+ user?: User | null;
214
+ config?: {
215
+ features?: Record<string, unknown>;
216
+ app?: {
217
+ id?: string;
218
+ name?: string;
219
+ environment?: string;
220
+ };
221
+ };
222
+ theme?: Theme;
223
+ router?: RouterState;
224
+ entities?: EntityDefinition[];
225
+ }
226
+ export interface SDKMessage {
227
+ id: number;
228
+ namespace: string;
229
+ type: string;
230
+ data: Record<string, unknown>;
231
+ }
232
+ export interface SDKResponse {
233
+ id: number;
234
+ success: boolean;
235
+ data?: unknown;
236
+ error?: string;
237
+ }
238
+ //# 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/vue.cjs ADDED
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const vue = require("vue");
4
+ const index = require("./index.cjs");
5
+ let client = null;
6
+ let isReady = null;
7
+ let user = null;
8
+ let isDark = null;
9
+ let themeMode = null;
10
+ let routerPath = null;
11
+ let routerQuery = null;
12
+ let routerHash = null;
13
+ let entities = null;
14
+ let initialized = false;
15
+ function initializeState() {
16
+ if (initialized) return;
17
+ client = index.createFoundationClient();
18
+ isReady = vue.ref(false);
19
+ user = vue.shallowRef(null);
20
+ isDark = vue.ref(false);
21
+ themeMode = vue.ref("system");
22
+ routerPath = vue.ref("/");
23
+ routerQuery = vue.shallowRef({});
24
+ routerHash = vue.ref("");
25
+ entities = vue.shallowRef([]);
26
+ client.ready.then(() => {
27
+ isReady.value = true;
28
+ user.value = client.auth.user;
29
+ isDark.value = client.theme.isDark;
30
+ themeMode.value = client.theme.mode;
31
+ routerPath.value = client.router.path;
32
+ routerQuery.value = client.router.query;
33
+ routerHash.value = client.router.hash;
34
+ entities.value = client.entities;
35
+ });
36
+ client.auth.onChange((newUser) => {
37
+ user.value = newUser;
38
+ });
39
+ client.theme.onChange((theme) => {
40
+ isDark.value = theme.isDark;
41
+ themeMode.value = theme.mode;
42
+ });
43
+ client.router.onChange((route) => {
44
+ routerPath.value = route.path;
45
+ routerQuery.value = route.query;
46
+ routerHash.value = route.hash;
47
+ });
48
+ initialized = true;
49
+ }
50
+ function useFoundation() {
51
+ initializeState();
52
+ return {
53
+ // Reactive state (readonly to prevent external mutation)
54
+ isReady: vue.readonly(isReady),
55
+ user: vue.readonly(user),
56
+ isDark: vue.readonly(isDark),
57
+ themeMode: vue.readonly(themeMode),
58
+ routerPath: vue.readonly(routerPath),
59
+ routerQuery: vue.readonly(routerQuery),
60
+ routerHash: vue.readonly(routerHash),
61
+ entities: vue.readonly(entities),
62
+ // Computed helpers
63
+ get isAuthenticated() {
64
+ return !!user.value;
65
+ },
66
+ get currentUser() {
67
+ return user.value;
68
+ },
69
+ // Direct access to SDK client for non-reactive operations
70
+ client,
71
+ // Shorthand service access
72
+ auth: client.auth,
73
+ ui: client.ui,
74
+ db: client.db,
75
+ router: client.router,
76
+ config: client.config,
77
+ files: client.files,
78
+ storage: client.storage,
79
+ log: client.log,
80
+ theme: client.theme,
81
+ stuff: client.stuff,
82
+ // Theme control methods
83
+ setTheme: (mode) => client.theme.setTheme(mode),
84
+ toggleTheme: () => client.theme.toggle(),
85
+ // Entity change subscription
86
+ onEntityChange: client.onEntityChange.bind(client)
87
+ };
88
+ }
89
+ exports.useFoundation = useFoundation;
90
+ //# sourceMappingURL=vue.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.cjs","sources":["../src/vue.ts"],"sourcesContent":["/**\n * Vue composable wrapper for Foundation SDK\n *\n * Provides Vue reactivity around the framework-agnostic SDK client.\n */\nimport { ref, readonly, shallowRef, type Ref, type ShallowRef, type DeepReadonly } from 'vue'\nimport { createFoundationClient } from './client'\nimport type {\n FoundationClient,\n User,\n Theme,\n RouterState,\n EntityDefinition,\n EntityChangeEvent\n} from './types'\n\n// Singleton client\nlet client: FoundationClient | null = null\n\n// Reactive state (module-level singletons)\nlet isReady: Ref<boolean> | null = null\nlet user: ShallowRef<User | null> | null = null\nlet isDark: Ref<boolean> | null = null\nlet themeMode: Ref<Theme['mode']> | null = null\nlet routerPath: Ref<string> | null = null\nlet routerQuery: ShallowRef<Record<string, string>> | null = null\nlet routerHash: Ref<string> | null = null\nlet entities: ShallowRef<EntityDefinition[]> | null = null\n\nlet initialized = false\n\nfunction initializeState() {\n if (initialized) return\n\n client = createFoundationClient()\n\n isReady = ref(false)\n user = shallowRef<User | null>(null)\n isDark = ref(false)\n themeMode = ref<Theme['mode']>('system')\n routerPath = ref('/')\n routerQuery = shallowRef<Record<string, string>>({})\n routerHash = ref('')\n entities = shallowRef<EntityDefinition[]>([])\n\n // Initialize reactive state when SDK is ready\n client.ready.then(() => {\n isReady!.value = true\n user!.value = client!.auth.user\n isDark!.value = client!.theme.isDark\n themeMode!.value = client!.theme.mode\n routerPath!.value = client!.router.path\n routerQuery!.value = client!.router.query\n routerHash!.value = client!.router.hash\n entities!.value = client!.entities\n })\n\n // Subscribe to changes\n client.auth.onChange((newUser) => {\n user!.value = newUser\n })\n\n client.theme.onChange((theme) => {\n isDark!.value = theme.isDark\n themeMode!.value = theme.mode\n })\n\n client.router.onChange((route) => {\n routerPath!.value = route.path\n routerQuery!.value = route.query\n routerHash!.value = route.hash\n })\n\n initialized = true\n}\n\nexport interface UseFoundationReturn {\n // Reactive state (readonly to prevent external mutation)\n isReady: DeepReadonly<Ref<boolean>>\n user: DeepReadonly<ShallowRef<User | null>>\n isDark: DeepReadonly<Ref<boolean>>\n themeMode: DeepReadonly<Ref<Theme['mode']>>\n routerPath: DeepReadonly<Ref<string>>\n routerQuery: DeepReadonly<ShallowRef<Record<string, string>>>\n routerHash: DeepReadonly<Ref<string>>\n entities: DeepReadonly<ShallowRef<EntityDefinition[]>>\n\n // Computed helpers\n readonly isAuthenticated: boolean\n readonly currentUser: User | null\n\n // Direct access to SDK client for non-reactive operations\n client: FoundationClient\n\n // Shorthand service access\n auth: FoundationClient['auth']\n ui: FoundationClient['ui']\n db: FoundationClient['db']\n router: FoundationClient['router']\n config: FoundationClient['config']\n files: FoundationClient['files']\n storage: FoundationClient['storage']\n log: FoundationClient['log']\n theme: FoundationClient['theme']\n stuff: FoundationClient['stuff']\n\n // Theme control methods\n setTheme: (mode: Theme['mode']) => Promise<void>\n toggleTheme: () => Promise<void>\n\n // Entity change subscription\n onEntityChange: (callback: (event: EntityChangeEvent) => void) => () => void\n}\n\n/**\n * Main composable for accessing Foundation SDK with Vue reactivity\n */\nexport function useFoundation(): UseFoundationReturn {\n initializeState()\n\n return {\n // Reactive state (readonly to prevent external mutation)\n isReady: readonly(isReady!),\n user: readonly(user!),\n isDark: readonly(isDark!),\n themeMode: readonly(themeMode!),\n routerPath: readonly(routerPath!),\n routerQuery: readonly(routerQuery!),\n routerHash: readonly(routerHash!),\n entities: readonly(entities!),\n\n // Computed helpers\n get isAuthenticated() {\n return !!user!.value\n },\n\n get currentUser() {\n return user!.value\n },\n\n // Direct access to SDK client for non-reactive operations\n client: client!,\n\n // Shorthand service access\n auth: client!.auth,\n ui: client!.ui,\n db: client!.db,\n router: client!.router,\n config: client!.config,\n files: client!.files,\n storage: client!.storage,\n log: client!.log,\n theme: client!.theme,\n stuff: client!.stuff,\n\n // Theme control methods\n setTheme: (mode: Theme['mode']) => client!.theme.setTheme(mode),\n toggleTheme: () => client!.theme.toggle(),\n\n // Entity change subscription\n onEntityChange: client!.onEntityChange.bind(client)\n }\n}\n\n// Re-export types for convenience\nexport type { User, Theme, RouterState, EntityDefinition, EntityChangeEvent }\n"],"names":["createFoundationClient","ref","shallowRef","readonly"],"mappings":";;;;AAiBA,IAAI,SAAkC;AAGtC,IAAI,UAA+B;AACnC,IAAI,OAAuC;AAC3C,IAAI,SAA8B;AAClC,IAAI,YAAuC;AAC3C,IAAI,aAAiC;AACrC,IAAI,cAAyD;AAC7D,IAAI,aAAiC;AACrC,IAAI,WAAkD;AAEtD,IAAI,cAAc;AAElB,SAAS,kBAAkB;AACzB,MAAI,YAAa;AAEjB,WAASA,MAAAA,uBAAA;AAET,YAAUC,IAAAA,IAAI,KAAK;AACnB,SAAOC,IAAAA,WAAwB,IAAI;AACnC,WAASD,IAAAA,IAAI,KAAK;AAClB,cAAYA,IAAAA,IAAmB,QAAQ;AACvC,eAAaA,IAAAA,IAAI,GAAG;AACpB,gBAAcC,IAAAA,WAAmC,EAAE;AACnD,eAAaD,IAAAA,IAAI,EAAE;AACnB,aAAWC,IAAAA,WAA+B,EAAE;AAG5C,SAAO,MAAM,KAAK,MAAM;AACtB,YAAS,QAAQ;AACjB,SAAM,QAAQ,OAAQ,KAAK;AAC3B,WAAQ,QAAQ,OAAQ,MAAM;AAC9B,cAAW,QAAQ,OAAQ,MAAM;AACjC,eAAY,QAAQ,OAAQ,OAAO;AACnC,gBAAa,QAAQ,OAAQ,OAAO;AACpC,eAAY,QAAQ,OAAQ,OAAO;AACnC,aAAU,QAAQ,OAAQ;AAAA,EAC5B,CAAC;AAGD,SAAO,KAAK,SAAS,CAAC,YAAY;AAChC,SAAM,QAAQ;AAAA,EAChB,CAAC;AAED,SAAO,MAAM,SAAS,CAAC,UAAU;AAC/B,WAAQ,QAAQ,MAAM;AACtB,cAAW,QAAQ,MAAM;AAAA,EAC3B,CAAC;AAED,SAAO,OAAO,SAAS,CAAC,UAAU;AAChC,eAAY,QAAQ,MAAM;AAC1B,gBAAa,QAAQ,MAAM;AAC3B,eAAY,QAAQ,MAAM;AAAA,EAC5B,CAAC;AAED,gBAAc;AAChB;AA2CO,SAAS,gBAAqC;AACnD,kBAAA;AAEA,SAAO;AAAA;AAAA,IAEL,SAASC,IAAAA,SAAS,OAAQ;AAAA,IAC1B,MAAMA,IAAAA,SAAS,IAAK;AAAA,IACpB,QAAQA,IAAAA,SAAS,MAAO;AAAA,IACxB,WAAWA,IAAAA,SAAS,SAAU;AAAA,IAC9B,YAAYA,IAAAA,SAAS,UAAW;AAAA,IAChC,aAAaA,IAAAA,SAAS,WAAY;AAAA,IAClC,YAAYA,IAAAA,SAAS,UAAW;AAAA,IAChC,UAAUA,IAAAA,SAAS,QAAS;AAAA;AAAA,IAG5B,IAAI,kBAAkB;AACpB,aAAO,CAAC,CAAC,KAAM;AAAA,IACjB;AAAA,IAEA,IAAI,cAAc;AAChB,aAAO,KAAM;AAAA,IACf;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA,MAAM,OAAQ;AAAA,IACd,IAAI,OAAQ;AAAA,IACZ,IAAI,OAAQ;AAAA,IACZ,QAAQ,OAAQ;AAAA,IAChB,QAAQ,OAAQ;AAAA,IAChB,OAAO,OAAQ;AAAA,IACf,SAAS,OAAQ;AAAA,IACjB,KAAK,OAAQ;AAAA,IACb,OAAO,OAAQ;AAAA,IACf,OAAO,OAAQ;AAAA;AAAA,IAGf,UAAU,CAAC,SAAwB,OAAQ,MAAM,SAAS,IAAI;AAAA,IAC9D,aAAa,MAAM,OAAQ,MAAM,OAAA;AAAA;AAAA,IAGjC,gBAAgB,OAAQ,eAAe,KAAK,MAAM;AAAA,EAAA;AAEtD;;"}
package/dist/vue.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { Ref, ShallowRef, DeepReadonly } from 'vue';
2
+ import { FoundationClient, User, Theme, RouterState, EntityDefinition, EntityChangeEvent } from './types';
3
+ export interface UseFoundationReturn {
4
+ isReady: DeepReadonly<Ref<boolean>>;
5
+ user: DeepReadonly<ShallowRef<User | null>>;
6
+ isDark: DeepReadonly<Ref<boolean>>;
7
+ themeMode: DeepReadonly<Ref<Theme['mode']>>;
8
+ routerPath: DeepReadonly<Ref<string>>;
9
+ routerQuery: DeepReadonly<ShallowRef<Record<string, string>>>;
10
+ routerHash: DeepReadonly<Ref<string>>;
11
+ entities: DeepReadonly<ShallowRef<EntityDefinition[]>>;
12
+ readonly isAuthenticated: boolean;
13
+ readonly currentUser: User | null;
14
+ client: FoundationClient;
15
+ auth: FoundationClient['auth'];
16
+ ui: FoundationClient['ui'];
17
+ db: FoundationClient['db'];
18
+ router: FoundationClient['router'];
19
+ config: FoundationClient['config'];
20
+ files: FoundationClient['files'];
21
+ storage: FoundationClient['storage'];
22
+ log: FoundationClient['log'];
23
+ theme: FoundationClient['theme'];
24
+ stuff: FoundationClient['stuff'];
25
+ setTheme: (mode: Theme['mode']) => Promise<void>;
26
+ toggleTheme: () => Promise<void>;
27
+ onEntityChange: (callback: (event: EntityChangeEvent) => void) => () => void;
28
+ }
29
+ /**
30
+ * Main composable for accessing Foundation SDK with Vue reactivity
31
+ */
32
+ export declare function useFoundation(): UseFoundationReturn;
33
+ export type { User, Theme, RouterState, EntityDefinition, EntityChangeEvent };
34
+ //# sourceMappingURL=vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAA6B,KAAK,GAAG,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,KAAK,CAAA;AAE7F,OAAO,KAAK,EACV,gBAAgB,EAChB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,SAAS,CAAA;AA8DhB,MAAM,WAAW,mBAAmB;IAElC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACnC,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAA;IAC3C,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAClC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3C,UAAU,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACrC,WAAW,EAAE,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAC7D,UAAU,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACrC,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAA;IAGtD,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAA;IAGjC,MAAM,EAAE,gBAAgB,CAAA;IAGxB,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAC9B,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC1B,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAClC,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAClC,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAChC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAA;IACpC,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAC5B,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAChC,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAGhC,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAGhC,cAAc,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;CAC7E;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,mBAAmB,CA6CnD;AAGD,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAA"}
package/dist/vue.js ADDED
@@ -0,0 +1,90 @@
1
+ import { readonly, ref, shallowRef } from "vue";
2
+ import { createFoundationClient } from "./index.js";
3
+ let client = null;
4
+ let isReady = null;
5
+ let user = null;
6
+ let isDark = null;
7
+ let themeMode = null;
8
+ let routerPath = null;
9
+ let routerQuery = null;
10
+ let routerHash = null;
11
+ let entities = null;
12
+ let initialized = false;
13
+ function initializeState() {
14
+ if (initialized) return;
15
+ client = createFoundationClient();
16
+ isReady = ref(false);
17
+ user = shallowRef(null);
18
+ isDark = ref(false);
19
+ themeMode = ref("system");
20
+ routerPath = ref("/");
21
+ routerQuery = shallowRef({});
22
+ routerHash = ref("");
23
+ entities = shallowRef([]);
24
+ client.ready.then(() => {
25
+ isReady.value = true;
26
+ user.value = client.auth.user;
27
+ isDark.value = client.theme.isDark;
28
+ themeMode.value = client.theme.mode;
29
+ routerPath.value = client.router.path;
30
+ routerQuery.value = client.router.query;
31
+ routerHash.value = client.router.hash;
32
+ entities.value = client.entities;
33
+ });
34
+ client.auth.onChange((newUser) => {
35
+ user.value = newUser;
36
+ });
37
+ client.theme.onChange((theme) => {
38
+ isDark.value = theme.isDark;
39
+ themeMode.value = theme.mode;
40
+ });
41
+ client.router.onChange((route) => {
42
+ routerPath.value = route.path;
43
+ routerQuery.value = route.query;
44
+ routerHash.value = route.hash;
45
+ });
46
+ initialized = true;
47
+ }
48
+ function useFoundation() {
49
+ initializeState();
50
+ return {
51
+ // Reactive state (readonly to prevent external mutation)
52
+ isReady: readonly(isReady),
53
+ user: readonly(user),
54
+ isDark: readonly(isDark),
55
+ themeMode: readonly(themeMode),
56
+ routerPath: readonly(routerPath),
57
+ routerQuery: readonly(routerQuery),
58
+ routerHash: readonly(routerHash),
59
+ entities: readonly(entities),
60
+ // Computed helpers
61
+ get isAuthenticated() {
62
+ return !!user.value;
63
+ },
64
+ get currentUser() {
65
+ return user.value;
66
+ },
67
+ // Direct access to SDK client for non-reactive operations
68
+ client,
69
+ // Shorthand service access
70
+ auth: client.auth,
71
+ ui: client.ui,
72
+ db: client.db,
73
+ router: client.router,
74
+ config: client.config,
75
+ files: client.files,
76
+ storage: client.storage,
77
+ log: client.log,
78
+ theme: client.theme,
79
+ stuff: client.stuff,
80
+ // Theme control methods
81
+ setTheme: (mode) => client.theme.setTheme(mode),
82
+ toggleTheme: () => client.theme.toggle(),
83
+ // Entity change subscription
84
+ onEntityChange: client.onEntityChange.bind(client)
85
+ };
86
+ }
87
+ export {
88
+ useFoundation
89
+ };
90
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.js","sources":["../src/vue.ts"],"sourcesContent":["/**\n * Vue composable wrapper for Foundation SDK\n *\n * Provides Vue reactivity around the framework-agnostic SDK client.\n */\nimport { ref, readonly, shallowRef, type Ref, type ShallowRef, type DeepReadonly } from 'vue'\nimport { createFoundationClient } from './client'\nimport type {\n FoundationClient,\n User,\n Theme,\n RouterState,\n EntityDefinition,\n EntityChangeEvent\n} from './types'\n\n// Singleton client\nlet client: FoundationClient | null = null\n\n// Reactive state (module-level singletons)\nlet isReady: Ref<boolean> | null = null\nlet user: ShallowRef<User | null> | null = null\nlet isDark: Ref<boolean> | null = null\nlet themeMode: Ref<Theme['mode']> | null = null\nlet routerPath: Ref<string> | null = null\nlet routerQuery: ShallowRef<Record<string, string>> | null = null\nlet routerHash: Ref<string> | null = null\nlet entities: ShallowRef<EntityDefinition[]> | null = null\n\nlet initialized = false\n\nfunction initializeState() {\n if (initialized) return\n\n client = createFoundationClient()\n\n isReady = ref(false)\n user = shallowRef<User | null>(null)\n isDark = ref(false)\n themeMode = ref<Theme['mode']>('system')\n routerPath = ref('/')\n routerQuery = shallowRef<Record<string, string>>({})\n routerHash = ref('')\n entities = shallowRef<EntityDefinition[]>([])\n\n // Initialize reactive state when SDK is ready\n client.ready.then(() => {\n isReady!.value = true\n user!.value = client!.auth.user\n isDark!.value = client!.theme.isDark\n themeMode!.value = client!.theme.mode\n routerPath!.value = client!.router.path\n routerQuery!.value = client!.router.query\n routerHash!.value = client!.router.hash\n entities!.value = client!.entities\n })\n\n // Subscribe to changes\n client.auth.onChange((newUser) => {\n user!.value = newUser\n })\n\n client.theme.onChange((theme) => {\n isDark!.value = theme.isDark\n themeMode!.value = theme.mode\n })\n\n client.router.onChange((route) => {\n routerPath!.value = route.path\n routerQuery!.value = route.query\n routerHash!.value = route.hash\n })\n\n initialized = true\n}\n\nexport interface UseFoundationReturn {\n // Reactive state (readonly to prevent external mutation)\n isReady: DeepReadonly<Ref<boolean>>\n user: DeepReadonly<ShallowRef<User | null>>\n isDark: DeepReadonly<Ref<boolean>>\n themeMode: DeepReadonly<Ref<Theme['mode']>>\n routerPath: DeepReadonly<Ref<string>>\n routerQuery: DeepReadonly<ShallowRef<Record<string, string>>>\n routerHash: DeepReadonly<Ref<string>>\n entities: DeepReadonly<ShallowRef<EntityDefinition[]>>\n\n // Computed helpers\n readonly isAuthenticated: boolean\n readonly currentUser: User | null\n\n // Direct access to SDK client for non-reactive operations\n client: FoundationClient\n\n // Shorthand service access\n auth: FoundationClient['auth']\n ui: FoundationClient['ui']\n db: FoundationClient['db']\n router: FoundationClient['router']\n config: FoundationClient['config']\n files: FoundationClient['files']\n storage: FoundationClient['storage']\n log: FoundationClient['log']\n theme: FoundationClient['theme']\n stuff: FoundationClient['stuff']\n\n // Theme control methods\n setTheme: (mode: Theme['mode']) => Promise<void>\n toggleTheme: () => Promise<void>\n\n // Entity change subscription\n onEntityChange: (callback: (event: EntityChangeEvent) => void) => () => void\n}\n\n/**\n * Main composable for accessing Foundation SDK with Vue reactivity\n */\nexport function useFoundation(): UseFoundationReturn {\n initializeState()\n\n return {\n // Reactive state (readonly to prevent external mutation)\n isReady: readonly(isReady!),\n user: readonly(user!),\n isDark: readonly(isDark!),\n themeMode: readonly(themeMode!),\n routerPath: readonly(routerPath!),\n routerQuery: readonly(routerQuery!),\n routerHash: readonly(routerHash!),\n entities: readonly(entities!),\n\n // Computed helpers\n get isAuthenticated() {\n return !!user!.value\n },\n\n get currentUser() {\n return user!.value\n },\n\n // Direct access to SDK client for non-reactive operations\n client: client!,\n\n // Shorthand service access\n auth: client!.auth,\n ui: client!.ui,\n db: client!.db,\n router: client!.router,\n config: client!.config,\n files: client!.files,\n storage: client!.storage,\n log: client!.log,\n theme: client!.theme,\n stuff: client!.stuff,\n\n // Theme control methods\n setTheme: (mode: Theme['mode']) => client!.theme.setTheme(mode),\n toggleTheme: () => client!.theme.toggle(),\n\n // Entity change subscription\n onEntityChange: client!.onEntityChange.bind(client)\n }\n}\n\n// Re-export types for convenience\nexport type { User, Theme, RouterState, EntityDefinition, EntityChangeEvent }\n"],"names":[],"mappings":";;AAiBA,IAAI,SAAkC;AAGtC,IAAI,UAA+B;AACnC,IAAI,OAAuC;AAC3C,IAAI,SAA8B;AAClC,IAAI,YAAuC;AAC3C,IAAI,aAAiC;AACrC,IAAI,cAAyD;AAC7D,IAAI,aAAiC;AACrC,IAAI,WAAkD;AAEtD,IAAI,cAAc;AAElB,SAAS,kBAAkB;AACzB,MAAI,YAAa;AAEjB,WAAS,uBAAA;AAET,YAAU,IAAI,KAAK;AACnB,SAAO,WAAwB,IAAI;AACnC,WAAS,IAAI,KAAK;AAClB,cAAY,IAAmB,QAAQ;AACvC,eAAa,IAAI,GAAG;AACpB,gBAAc,WAAmC,EAAE;AACnD,eAAa,IAAI,EAAE;AACnB,aAAW,WAA+B,EAAE;AAG5C,SAAO,MAAM,KAAK,MAAM;AACtB,YAAS,QAAQ;AACjB,SAAM,QAAQ,OAAQ,KAAK;AAC3B,WAAQ,QAAQ,OAAQ,MAAM;AAC9B,cAAW,QAAQ,OAAQ,MAAM;AACjC,eAAY,QAAQ,OAAQ,OAAO;AACnC,gBAAa,QAAQ,OAAQ,OAAO;AACpC,eAAY,QAAQ,OAAQ,OAAO;AACnC,aAAU,QAAQ,OAAQ;AAAA,EAC5B,CAAC;AAGD,SAAO,KAAK,SAAS,CAAC,YAAY;AAChC,SAAM,QAAQ;AAAA,EAChB,CAAC;AAED,SAAO,MAAM,SAAS,CAAC,UAAU;AAC/B,WAAQ,QAAQ,MAAM;AACtB,cAAW,QAAQ,MAAM;AAAA,EAC3B,CAAC;AAED,SAAO,OAAO,SAAS,CAAC,UAAU;AAChC,eAAY,QAAQ,MAAM;AAC1B,gBAAa,QAAQ,MAAM;AAC3B,eAAY,QAAQ,MAAM;AAAA,EAC5B,CAAC;AAED,gBAAc;AAChB;AA2CO,SAAS,gBAAqC;AACnD,kBAAA;AAEA,SAAO;AAAA;AAAA,IAEL,SAAS,SAAS,OAAQ;AAAA,IAC1B,MAAM,SAAS,IAAK;AAAA,IACpB,QAAQ,SAAS,MAAO;AAAA,IACxB,WAAW,SAAS,SAAU;AAAA,IAC9B,YAAY,SAAS,UAAW;AAAA,IAChC,aAAa,SAAS,WAAY;AAAA,IAClC,YAAY,SAAS,UAAW;AAAA,IAChC,UAAU,SAAS,QAAS;AAAA;AAAA,IAG5B,IAAI,kBAAkB;AACpB,aAAO,CAAC,CAAC,KAAM;AAAA,IACjB;AAAA,IAEA,IAAI,cAAc;AAChB,aAAO,KAAM;AAAA,IACf;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA,MAAM,OAAQ;AAAA,IACd,IAAI,OAAQ;AAAA,IACZ,IAAI,OAAQ;AAAA,IACZ,QAAQ,OAAQ;AAAA,IAChB,QAAQ,OAAQ;AAAA,IAChB,OAAO,OAAQ;AAAA,IACf,SAAS,OAAQ;AAAA,IACjB,KAAK,OAAQ;AAAA,IACb,OAAO,OAAQ;AAAA,IACf,OAAO,OAAQ;AAAA;AAAA,IAGf,UAAU,CAAC,SAAwB,OAAQ,MAAM,SAAS,IAAI;AAAA,IAC9D,aAAa,MAAM,OAAQ,MAAM,OAAA;AAAA;AAAA,IAGjC,gBAAgB,OAAQ,eAAe,KAAK,MAAM;AAAA,EAAA;AAEtD;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foundation-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.11",
4
4
  "description": "SDK for apps embedded in the Foundation container iframe",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -16,6 +16,16 @@
16
16
  "types": "./dist/index.d.ts",
17
17
  "default": "./dist/index.cjs"
18
18
  }
19
+ },
20
+ "./vue": {
21
+ "import": {
22
+ "types": "./dist/vue.d.ts",
23
+ "default": "./dist/vue.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/vue.d.ts",
27
+ "default": "./dist/vue.cjs"
28
+ }
19
29
  }
20
30
  },
21
31
  "files": [
@@ -36,10 +46,19 @@
36
46
  ],
37
47
  "author": "",
38
48
  "license": "MIT",
49
+ "peerDependencies": {
50
+ "vue": "^3.0.0"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "vue": {
54
+ "optional": true
55
+ }
56
+ },
39
57
  "devDependencies": {
40
58
  "typescript": "^5.0.0",
41
59
  "vite": "^6.0.0",
42
- "vite-plugin-dts": "^4.0.0"
60
+ "vite-plugin-dts": "^4.0.0",
61
+ "vue": "^3.5.0"
43
62
  },
44
63
  "sideEffects": false
45
64
  }