foundation-sdk 0.1.12 → 0.1.13

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 ADDED
@@ -0,0 +1,563 @@
1
+ # foundation-sdk
2
+
3
+ SDK for building applications that embed within the Foundation container.
4
+
5
+ > **Future Migration:** This package will be renamed to `@foundation/iframe-sdk` when the npm organization is set up.
6
+
7
+ ## Installation
8
+
9
+ ```bash
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
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### Vanilla TypeScript/JavaScript
22
+
23
+ ```typescript
24
+ import { createFoundationClient } from 'foundation-sdk'
25
+
26
+ const sdk = createFoundationClient()
27
+
28
+ // Wait for SDK to be ready (receives initial state from container)
29
+ await sdk.ready
30
+
31
+ // Access current user
32
+ console.log(sdk.auth.user)
33
+
34
+ // Fetch data
35
+ const { items } = await sdk.db.list('projects', { limit: 10 })
36
+
37
+ // Show a toast notification
38
+ await sdk.ui.toast('Hello from embedded app!', 'success')
39
+ ```
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
+
61
+ ## API Reference
62
+
63
+ ### Initialization
64
+
65
+ #### `createFoundationClient(): FoundationClient`
66
+
67
+ Creates or returns the singleton SDK client instance.
68
+
69
+ ```typescript
70
+ const sdk = createFoundationClient()
71
+
72
+ // Check if ready
73
+ if (sdk.isReady) {
74
+ // SDK has received initial state
75
+ }
76
+
77
+ // Wait for ready
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()
92
+ ```
93
+
94
+ ---
95
+
96
+ ### Authentication (`sdk.auth`)
97
+
98
+ ```typescript
99
+ interface AuthService {
100
+ readonly user: User | null // Current user
101
+ readonly isAuthenticated: boolean // Is user logged in
102
+ getToken(): Promise<string> // Get auth token
103
+ login(): Promise<void> // Trigger login flow
104
+ logout(): Promise<void> // Trigger logout
105
+ onChange(callback): () => void // Subscribe to auth changes
106
+ }
107
+ ```
108
+
109
+ **Example:**
110
+
111
+ ```typescript
112
+ // Get current user
113
+ const user = sdk.auth.user
114
+ console.log(user?.email, user?.name)
115
+
116
+ // Get token for API calls
117
+ const token = await sdk.auth.getToken()
118
+
119
+ // Subscribe to auth changes
120
+ const unsubscribe = sdk.auth.onChange((user) => {
121
+ console.log('Auth changed:', user)
122
+ })
123
+ ```
124
+
125
+ ---
126
+
127
+ ### Database (`sdk.db`)
128
+
129
+ ```typescript
130
+ interface DbService {
131
+ list<T>(entity: string, options?: ListOptions): Promise<{ items: T[]; nextCursor?: string }>
132
+ get<T>(entity: string, id: string): Promise<T>
133
+ create<T>(entity: string, data: Partial<T>): Promise<T>
134
+ update<T>(entity: string, id: string, updates: Partial<T>): Promise<T>
135
+ delete(entity: string, id: string): Promise<void>
136
+ }
137
+
138
+ interface ListOptions {
139
+ filters?: Record<string, unknown>
140
+ limit?: number
141
+ cursor?: string
142
+ orderBy?: string
143
+ orderDir?: 'asc' | 'desc'
144
+ }
145
+ ```
146
+
147
+ **Example:**
148
+
149
+ ```typescript
150
+ // List with filters and pagination
151
+ const { items, nextCursor } = await sdk.db.list('projects', {
152
+ filters: { status: 'active' },
153
+ limit: 20,
154
+ orderBy: 'createdAt',
155
+ orderDir: 'desc'
156
+ })
157
+
158
+ // Get single item
159
+ const project = await sdk.db.get('projects', 'project-123')
160
+
161
+ // Create
162
+ const newProject = await sdk.db.create('projects', {
163
+ name: 'New Project',
164
+ status: 'active'
165
+ })
166
+
167
+ // Update
168
+ const updated = await sdk.db.update('projects', 'project-123', {
169
+ name: 'Updated Name'
170
+ })
171
+
172
+ // Delete
173
+ await sdk.db.delete('projects', 'project-123')
174
+ ```
175
+
176
+ ---
177
+
178
+ ### UI (`sdk.ui`)
179
+
180
+ ```typescript
181
+ interface UIService {
182
+ toast(message: string, type?: 'success' | 'error' | 'warn' | 'info'): Promise<void>
183
+ confirm(message: string): Promise<{ confirmed: boolean }>
184
+ loading: {
185
+ show(message?: string): Promise<void>
186
+ hide(): Promise<void>
187
+ }
188
+ banner: {
189
+ show(message: string, options?: BannerOptions): Promise<{ bannerId: string }>
190
+ hide(bannerId: string): Promise<void>
191
+ }
192
+ }
193
+ ```
194
+
195
+ **Example:**
196
+
197
+ ```typescript
198
+ // Toast notifications
199
+ await sdk.ui.toast('Operation successful', 'success')
200
+ await sdk.ui.toast('Something went wrong', 'error')
201
+
202
+ // Confirmation dialog
203
+ const { confirmed } = await sdk.ui.confirm('Delete this item?')
204
+ if (confirmed) {
205
+ await sdk.db.delete('items', itemId)
206
+ }
207
+
208
+ // Loading overlay
209
+ sdk.ui.loading.show('Processing...')
210
+ try {
211
+ await doSomething()
212
+ } finally {
213
+ sdk.ui.loading.hide()
214
+ }
215
+
216
+ // Banners
217
+ const { bannerId } = await sdk.ui.banner.show('New feature available!', {
218
+ type: 'info',
219
+ dismissible: true
220
+ })
221
+ // Later...
222
+ await sdk.ui.banner.hide(bannerId)
223
+ ```
224
+
225
+ ---
226
+
227
+ ### Router (`sdk.router`)
228
+
229
+ ```typescript
230
+ interface RouterService {
231
+ readonly path: string
232
+ readonly query: Record<string, string>
233
+ readonly hash: string
234
+ push(path: string, options?: NavOptions): Promise<void>
235
+ replace(path: string, options?: NavOptions): Promise<void>
236
+ setQuery(params: Record<string, string>, options?: { replace?: boolean }): Promise<void>
237
+ onChange(callback: (route: RouterState) => void): () => void
238
+ }
239
+ ```
240
+
241
+ **Example:**
242
+
243
+ ```typescript
244
+ // Navigate
245
+ await sdk.router.push('/dashboard')
246
+ await sdk.router.push('/projects', { query: { filter: 'active' } })
247
+
248
+ // Replace (no history entry)
249
+ await sdk.router.replace('/login')
250
+
251
+ // Update query params
252
+ await sdk.router.setQuery({ page: '2', sort: 'name' })
253
+
254
+ // Subscribe to route changes
255
+ const unsubscribe = sdk.router.onChange((route) => {
256
+ console.log('Route changed:', route.path, route.query)
257
+ })
258
+ ```
259
+
260
+ ---
261
+
262
+ ### Theme (`sdk.theme`)
263
+
264
+ ```typescript
265
+ interface ThemeService {
266
+ readonly isDark: boolean
267
+ readonly mode: 'light' | 'dark' | 'system'
268
+ setTheme(mode: 'light' | 'dark' | 'system'): Promise<void>
269
+ toggle(): Promise<void>
270
+ onChange(callback: (theme: Theme) => void): () => void
271
+ }
272
+ ```
273
+
274
+ **Example:**
275
+
276
+ ```typescript
277
+ // Check current theme
278
+ if (sdk.theme.isDark) {
279
+ // Apply dark styles
280
+ }
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
+
289
+ // Subscribe to theme changes
290
+ const unsubscribe = sdk.theme.onChange((theme) => {
291
+ document.body.classList.toggle('dark', theme.isDark)
292
+ })
293
+ ```
294
+
295
+ ---
296
+
297
+ ### Storage (`sdk.storage`)
298
+
299
+ ```typescript
300
+ interface StorageService {
301
+ upload(options: UploadOptions): Promise<{ id: string; url: string; name: string }>
302
+ get(fileId: string): Promise<FileMetadata>
303
+ delete(fileId: string): Promise<void>
304
+ list(options?: ListOptions): Promise<{ items: FileMetadata[]; nextCursor?: string }>
305
+ }
306
+ ```
307
+
308
+ **Example:**
309
+
310
+ ```typescript
311
+ // Upload a file (base64 encoded)
312
+ const file = await sdk.storage.upload({
313
+ name: 'document.pdf',
314
+ type: 'application/pdf',
315
+ size: fileBuffer.byteLength,
316
+ data: btoa(String.fromCharCode(...new Uint8Array(fileBuffer))),
317
+ folder: 'documents'
318
+ })
319
+
320
+ console.log(file.url) // URL to access the file
321
+
322
+ // List files
323
+ const { items } = await sdk.storage.list({ folder: 'documents' })
324
+ ```
325
+
326
+ ---
327
+
328
+ ### Files (`sdk.files`)
329
+
330
+ For large file uploads using presigned URLs:
331
+
332
+ ```typescript
333
+ interface FilesService {
334
+ initiate(options: InitiateOptions): Promise<{
335
+ id: string
336
+ name: string
337
+ signedUrl: string
338
+ signedData: Record<string, string>
339
+ }>
340
+ get(fileId: string): Promise<FileMetadata>
341
+ delete(fileId: string): Promise<void>
342
+ list(options?: ListOptions): Promise<{ items: FileMetadata[]; nextCursor?: string }>
343
+ }
344
+ ```
345
+
346
+ **Example:**
347
+
348
+ ```typescript
349
+ // Initiate upload to get presigned URL
350
+ const { signedUrl, signedData, id } = await sdk.files.initiate({
351
+ name: 'large-video.mp4',
352
+ contentType: 'video/mp4',
353
+ contentLength: file.size
354
+ })
355
+
356
+ // Upload directly to storage
357
+ const formData = new FormData()
358
+ Object.entries(signedData).forEach(([key, value]) => {
359
+ formData.append(key, value)
360
+ })
361
+ formData.append('file', file)
362
+
363
+ await fetch(signedUrl, { method: 'POST', body: formData })
364
+ ```
365
+
366
+ ---
367
+
368
+ ### Logging (`sdk.log`)
369
+
370
+ ```typescript
371
+ interface LogService {
372
+ info(message: string, data?: Record<string, unknown>): void
373
+ warn(message: string, data?: Record<string, unknown>): void
374
+ error(message: string, data?: Record<string, unknown>): void
375
+ event(name: string, properties?: Record<string, unknown>): void
376
+ }
377
+ ```
378
+
379
+ **Example:**
380
+
381
+ ```typescript
382
+ // Log messages
383
+ sdk.log.info('User completed onboarding', { userId: user.id })
384
+ sdk.log.warn('API rate limit approaching', { remaining: 10 })
385
+ sdk.log.error('Failed to save', { error: err.message })
386
+
387
+ // Track analytics events
388
+ sdk.log.event('button_clicked', { buttonId: 'submit', page: 'checkout' })
389
+ ```
390
+
391
+ ---
392
+
393
+ ### Config (`sdk.config`)
394
+
395
+ ```typescript
396
+ interface ConfigService {
397
+ readonly features: Record<string, unknown>
398
+ readonly app: { id?: string; name?: string; environment?: string }
399
+ get(key: string): Promise<unknown>
400
+ }
401
+ ```
402
+
403
+ **Example:**
404
+
405
+ ```typescript
406
+ // Check feature flags
407
+ if (sdk.config.features.newDashboard) {
408
+ // Show new dashboard
409
+ }
410
+
411
+ // Get app info
412
+ console.log(sdk.config.app.environment) // 'production' | 'staging' | 'development'
413
+
414
+ // Get specific config value
415
+ const apiUrl = await sdk.config.get('apiBaseUrl')
416
+ ```
417
+
418
+ ---
419
+
420
+ ### Entity Changes
421
+
422
+ Subscribe to real-time entity changes for cache invalidation:
423
+
424
+ ```typescript
425
+ const unsubscribe = sdk.onEntityChange((event) => {
426
+ console.log('Entity changed:', event)
427
+ // event.changeType: 'entity.created' | 'entity.updated' | 'entity.deleted'
428
+ // event.entityId: 'projects'
429
+ // event.id: 'project-123'
430
+
431
+ // Invalidate your cache
432
+ if (event.entityId === 'projects') {
433
+ refetchProjects()
434
+ }
435
+ })
436
+ ```
437
+
438
+ ---
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
+
530
+ ## TypeScript
531
+
532
+ Full TypeScript support with exported types:
533
+
534
+ ```typescript
535
+ import type {
536
+ FoundationClient,
537
+ User,
538
+ Theme,
539
+ RouterState,
540
+ EntityDefinition,
541
+ EntityChangeEvent,
542
+ AuthService,
543
+ ThemeService,
544
+ RouterService,
545
+ DbService,
546
+ UIService,
547
+ StorageService,
548
+ FilesService,
549
+ FileMetadata,
550
+ LogService,
551
+ ConfigService
552
+ } from 'foundation-sdk'
553
+ ```
554
+
555
+ ---
556
+
557
+ ## Architecture
558
+
559
+ See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed diagrams of how the SDK communicates with the container.
560
+
561
+ ## License
562
+
563
+ MIT
package/dist/index.cjs CHANGED
@@ -255,8 +255,11 @@ function createFoundationClient() {
255
255
  return isReady;
256
256
  },
257
257
  auth: authService,
258
+ // only logout - this is problematic - provides user and account
258
259
  theme: themeService,
260
+ // only useful for themed tailwind projects - still useful anyway
259
261
  router: routerService,
262
+ // once you're in app - external or container-ui level routing it just not very useful.
260
263
  db: dbService,
261
264
  ui: uiService,
262
265
  storage: storageService,
@@ -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 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,\n theme: themeService,\n router: routerService,\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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"}
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.js CHANGED
@@ -253,8 +253,11 @@ function createFoundationClient() {
253
253
  return isReady;
254
254
  },
255
255
  auth: authService,
256
+ // only logout - this is problematic - provides user and account
256
257
  theme: themeService,
258
+ // only useful for themed tailwind projects - still useful anyway
257
259
  router: routerService,
260
+ // once you're in app - external or container-ui level routing it just not very useful.
258
261
  db: dbService,
259
262
  ui: uiService,
260
263
  storage: storageService,
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 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,\n theme: themeService,\n router: routerService,\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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"}
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foundation-sdk",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "SDK for apps embedded in the Foundation container iframe",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",