foundation-sdk 0.1.1 → 0.1.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAiBjB,MAAM,SAAS,CAAA;AAIhB,wBAAgB,sBAAsB,IAAI,gBAAgB,CA4OzD;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
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;
@@ -235,17 +255,15 @@ function createFoundationClient() {
235
255
  return isReady;
236
256
  },
237
257
  auth: authService,
238
- // only logout - this is problematic - provides user and account
239
258
  theme: themeService,
240
- // only useful for themed tailwind projects - still useful anyway
241
259
  router: routerService,
242
- // once you're in app - external or container-ui level routing it just not very useful.
243
260
  db: dbService,
244
261
  ui: uiService,
245
262
  storage: storageService,
246
263
  files: filesService,
247
264
  log: logService,
248
265
  config: configService,
266
+ stuff: stuffService,
249
267
  onEntityChange(callback) {
250
268
  entityListeners.push(callback);
251
269
  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":"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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,\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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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
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 } from './types';
2
+ export type { FoundationClient, User, Theme, RouterState, EntityDefinition, EntityChangeEvent, AuthService, ThemeService, RouterService, DbService, UIService, StorageService, FilesService, FileMetadata, LogService, ConfigService, StuffService, StuffItem } from './types';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,EACd,MAAM,SAAS,CAAA"}
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;
@@ -233,17 +253,15 @@ function createFoundationClient() {
233
253
  return isReady;
234
254
  },
235
255
  auth: authService,
236
- // only logout - this is problematic - provides user and account
237
256
  theme: themeService,
238
- // only useful for themed tailwind projects - still useful anyway
239
257
  router: routerService,
240
- // once you're in app - external or container-ui level routing it just not very useful.
241
258
  db: dbService,
242
259
  ui: uiService,
243
260
  storage: storageService,
244
261
  files: filesService,
245
262
  log: logService,
246
263
  config: configService,
264
+ stuff: stuffService,
247
265
  onEntityChange(callback) {
248
266
  entityListeners.push(callback);
249
267
  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,\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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"}
package/dist/types.d.ts CHANGED
@@ -116,12 +116,28 @@ export interface FilesService {
116
116
  contentType: string;
117
117
  contentLength: number;
118
118
  metadata?: Record<string, unknown>;
119
+ sha256: string;
119
120
  }): Promise<{
120
121
  id: string;
121
122
  name: string;
122
123
  signedUrl: string;
123
124
  signedData: Record<string, string>;
124
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
+ }>;
125
141
  get(fileId: string): Promise<FileMetadata>;
126
142
  delete(fileId: string): Promise<void>;
127
143
  list(options?: {
@@ -148,6 +164,19 @@ export interface LogService {
148
164
  error(message: string, data?: Record<string, unknown>): void;
149
165
  event(name: string, properties?: Record<string, unknown>): void;
150
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
+ }
151
180
  export interface ConfigService {
152
181
  readonly features: Record<string, unknown>;
153
182
  readonly app: {
@@ -176,6 +205,7 @@ export interface FoundationClient {
176
205
  files: FilesService;
177
206
  log: LogService;
178
207
  config: ConfigService;
208
+ stuff: StuffService;
179
209
  onEntityChange(callback: (event: EntityChangeEvent) => void): () => void;
180
210
  readonly entities: EntityDefinition[];
181
211
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/vue.cjs CHANGED
@@ -78,6 +78,7 @@ function useFoundation() {
78
78
  storage: client.storage,
79
79
  log: client.log,
80
80
  theme: client.theme,
81
+ stuff: client.stuff,
81
82
  // Theme control methods
82
83
  setTheme: (mode) => client.theme.setTheme(mode),
83
84
  toggleTheme: () => client.theme.toggle(),
package/dist/vue.cjs.map CHANGED
@@ -1 +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\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\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;AA0CO,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;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;;"}
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 CHANGED
@@ -21,6 +21,7 @@ export interface UseFoundationReturn {
21
21
  storage: FoundationClient['storage'];
22
22
  log: FoundationClient['log'];
23
23
  theme: FoundationClient['theme'];
24
+ stuff: FoundationClient['stuff'];
24
25
  setTheme: (mode: Theme['mode']) => Promise<void>;
25
26
  toggleTheme: () => Promise<void>;
26
27
  onEntityChange: (callback: (event: EntityChangeEvent) => void) => () => void;
package/dist/vue.d.ts.map CHANGED
@@ -1 +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;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,CA4CnD;AAGD,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAA"}
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 CHANGED
@@ -76,6 +76,7 @@ function useFoundation() {
76
76
  storage: client.storage,
77
77
  log: client.log,
78
78
  theme: client.theme,
79
+ stuff: client.stuff,
79
80
  // Theme control methods
80
81
  setTheme: (mode) => client.theme.setTheme(mode),
81
82
  toggleTheme: () => client.theme.toggle(),
package/dist/vue.js.map CHANGED
@@ -1 +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\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\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;AA0CO,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;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;"}
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.1",
3
+ "version": "0.1.12",
4
4
  "description": "SDK for apps embedded in the Foundation container iframe",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
package/README.md DELETED
@@ -1,563 +0,0 @@
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