@lyeve-labs/client-svelte 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @lyeve/cms-client-svelte
2
2
 
3
- Svelte 5 reactive stores for the LyEve Core API. Thin wrapper around
3
+ Svelte 5 reactive stores for the LyEve CMS API. Thin wrapper around
4
4
  `@lyeve/cms-client` using Svelte 5 runes (`$state`).
5
5
 
6
6
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
package/dist/index.cjs CHANGED
@@ -27,11 +27,11 @@ __export(src_exports, {
27
27
  });
28
28
  module.exports = __toCommonJS(src_exports);
29
29
 
30
- // src/runes.ts
31
- var import_cms_client = require("@lyeve/cms-client");
30
+ // src/runes.svelte.ts
31
+ var import_client = require("@lyeve-labs/client");
32
32
  function createCmsClient(config) {
33
33
  const base = config.baseUrl ?? "";
34
- return (0, import_cms_client.createClient)((url, init) => {
34
+ return (0, import_client.createClient)((url, init) => {
35
35
  const fullUrl = typeof url === "string" ? `${base}${url}` : url;
36
36
  return fetch(fullUrl, {
37
37
  ...init,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/runes.ts"],"sourcesContent":["// Re-exports for non-Svelte consumers (bundled by tsup).\n// Implementation lives in runes.svelte.ts so Svelte's compiler handles\n// $state runes natively via the \"svelte\" export condition.\nexport {\n\tcreateCmsClient,\n\tcreateAsyncStore,\n\tcreateMutation,\n\tcreateAuthStore,\n\ttype SvelteCmsConfig,\n\ttype AsyncStore,\n\ttype AuthState,\n\ttype AuthStore,\n} from './runes.js';\n","import { createClient, type HttpClient } from '@lyeve/cms-client';\n\n// Client factory\n\nexport interface SvelteCmsConfig {\n\t/** Base URL prepended to every request path. */\n\tbaseUrl?: string;\n\t/**\n\t * Callback returning headers added to every request.\n\t * Called on every request so auth tokens can be refreshed without\n\t * recreating the client.\n\t */\n\tgetHeaders?: () => Record<string, string>;\n}\n\n/**\n * Creates an HttpClient pre-configured with base URL and dynamic request\n * headers. No Provider needed - Svelte callers just pass the client around.\n *\n * @example\n * ```ts\n * const client = createCmsClient({\n * baseUrl: 'https://cms.example.com',\n * getHeaders: () => ({ Authorization: `Bearer ${token}` }),\n * });\n * ```\n */\nexport function createCmsClient(config: SvelteCmsConfig): HttpClient {\n\tconst base = config.baseUrl ?? '';\n\treturn createClient((url, init) => {\n\t\tconst fullUrl = typeof url === 'string' ? `${base}${url}` : url;\n\t\treturn fetch(fullUrl, {\n\t\t\t...init,\n\t\t\theaders: { ...init?.headers, ...config.getHeaders?.() },\n\t\t});\n\t});\n}\n\n// Generic async store\n\nexport interface AsyncStore<T> {\n\treadonly data: T | null;\n\treadonly error: Error | null;\n\treadonly loading: boolean;\n\trefetch: () => void;\n}\n\n/**\n * Reactive async data store using the $state rune.\n * Fires the fetcher immediately and exposes reactive loading/data/error\n * getters that Svelte components can read directly in markup.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const schemas = createAsyncStore((c) => getSchemas(c), client);\n * </script>\n * {#if schemas.loading}...{/if}\n * ```\n */\nexport function createAsyncStore<T>(\n\tfetcher: (client: HttpClient) => Promise<T>,\n\tclient: HttpClient,\n): AsyncStore<T> {\n\tlet data = $state<T | null>(null);\n\tlet error = $state<Error | null>(null);\n\tlet loading = $state(true);\n\n\tasync function fetch() {\n\t\tloading = true;\n\t\ttry {\n\t\t\tdata = await fetcher(client);\n\t\t\terror = null;\n\t\t} catch (e) {\n\t\t\terror = e as Error;\n\t\t} finally {\n\t\t\tloading = false;\n\t\t}\n\t}\n\n\tfetch();\n\n\treturn {\n\t\tget data() { return data; },\n\t\tget error() { return error; },\n\t\tget loading() { return loading; },\n\t\trefetch: fetch,\n\t};\n}\n\n/**\n * Reactive mutation primitive using the $state rune.\n * Returns data/error/loading state and a run function that triggers the\n * mutation. Unlike createAsyncStore, the mutation does not fire immediately.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const createArticle = createMutation(\n * (c, vars: { title: string }) => createArticle(c, vars),\n * client,\n * );\n * </script>\n * <button onclick={() => createArticle.run({ title: 'Hello' })}>\n * {createArticle.loading ? 'Saving...' : 'Create'}\n * </button>\n * ```\n */\nexport function createMutation<T, V>(\n\tmutator: (client: HttpClient, vars: V) => Promise<T>,\n\tclient: HttpClient,\n) {\n\tlet data = $state<T | null>(null);\n\tlet error = $state<Error | null>(null);\n\tlet loading = $state(false);\n\n\tasync function run(vars: V): Promise<T> {\n\t\tloading = true;\n\t\terror = null;\n\t\ttry {\n\t\t\tconst result = await mutator(client, vars);\n\t\t\tdata = result;\n\t\t\treturn result;\n\t\t} catch (e) {\n\t\t\terror = e as Error;\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tloading = false;\n\t\t}\n\t}\n\n\treturn {\n\t\tget data() { return data; },\n\t\tget error() { return error; },\n\t\tget loading() { return loading; },\n\t\trun,\n\t};\n}\n\n// Auth store\n\nexport interface AuthState {\n\tuser: { id: string; email: string; roles: string[] } | null;\n\ttoken: string | null;\n}\n\nexport interface AuthStore {\n\treadonly user: AuthState['user'];\n\treadonly token: string | null;\n\treadonly isAuthenticated: boolean;\n\t/** Set the current user and token after a successful login. */\n\tsetUser: (user: AuthState['user'], token: string | null) => void;\n\t/** Clear auth state (e.g. after logout). */\n\tclear: () => void;\n\t/** Try to load the current user from the server using the stored token. */\n\tload: () => Promise<void>;\n}\n\n/**\n * Simple reactive auth store. The caller is responsible for calling\n * {@link AuthStore.setUser} after login and {@link AuthStore.clear} after\n * logout. Use {@link AuthStore.load} on app start to restore a session\n * from an existing cookie.\n */\nexport function createAuthStore(client: HttpClient): AuthStore {\n\tlet state = $state<AuthState>({ user: null, token: null });\n\n\treturn {\n\t\tget user() { return state.user; },\n\t\tget token() { return state.token; },\n\t\tget isAuthenticated() { return state.token !== null; },\n\t\tsetUser(user: AuthState['user'], token: string | null) {\n\t\t\tstate = { user, token };\n\t\t},\n\t\tclear() {\n\t\t\tstate = { user: null, token: null };\n\t\t},\n\t\tasync load() {\n\t\t\ttry {\n\t\t\t\tconst user = await client.get<{ id: string; email: string; roles: string[] }>('/api/admin/auth/me');\n\t\t\t\tstate = { ...state, user };\n\t\t\t} catch { /* not logged in */ }\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,wBAA8C;AA2BvC,SAAS,gBAAgB,QAAqC;AACpE,QAAM,OAAO,OAAO,WAAW;AAC/B,aAAO,gCAAa,CAAC,KAAK,SAAS;AAClC,UAAM,UAAU,OAAO,QAAQ,WAAW,GAAG,IAAI,GAAG,GAAG,KAAK;AAC5D,WAAO,MAAM,SAAS;AAAA,MACrB,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,MAAM,SAAS,GAAG,OAAO,aAAa,EAAE;AAAA,IACvD,CAAC;AAAA,EACF,CAAC;AACF;AAwBO,SAAS,iBACf,SACA,QACgB;AAChB,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,IAAI;AAEzB,iBAAeA,SAAQ;AACtB,cAAU;AACV,QAAI;AACH,aAAO,MAAM,QAAQ,MAAM;AAC3B,cAAQ;AAAA,IACT,SAAS,GAAG;AACX,cAAQ;AAAA,IACT,UAAE;AACD,gBAAU;AAAA,IACX;AAAA,EACD;AAEA,EAAAA,OAAM;AAEN,SAAO;AAAA,IACN,IAAI,OAAO;AAAE,aAAO;AAAA,IAAM;AAAA,IAC1B,IAAI,QAAQ;AAAE,aAAO;AAAA,IAAO;AAAA,IAC5B,IAAI,UAAU;AAAE,aAAO;AAAA,IAAS;AAAA,IAChC,SAASA;AAAA,EACV;AACD;AAoBO,SAAS,eACf,SACA,QACC;AACD,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,KAAK;AAE1B,iBAAe,IAAI,MAAqB;AACvC,cAAU;AACV,YAAQ;AACR,QAAI;AACH,YAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI;AACzC,aAAO;AACP,aAAO;AAAA,IACR,SAAS,GAAG;AACX,cAAQ;AACR,YAAM;AAAA,IACP,UAAE;AACD,gBAAU;AAAA,IACX;AAAA,EACD;AAEA,SAAO;AAAA,IACN,IAAI,OAAO;AAAE,aAAO;AAAA,IAAM;AAAA,IAC1B,IAAI,QAAQ;AAAE,aAAO;AAAA,IAAO;AAAA,IAC5B,IAAI,UAAU;AAAE,aAAO;AAAA,IAAS;AAAA,IAChC;AAAA,EACD;AACD;AA2BO,SAAS,gBAAgB,QAA+B;AAC9D,MAAI,QAAQ,OAAkB,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC;AAEzD,SAAO;AAAA,IACN,IAAI,OAAO;AAAE,aAAO,MAAM;AAAA,IAAM;AAAA,IAChC,IAAI,QAAQ;AAAE,aAAO,MAAM;AAAA,IAAO;AAAA,IAClC,IAAI,kBAAkB;AAAE,aAAO,MAAM,UAAU;AAAA,IAAM;AAAA,IACrD,QAAQ,MAAyB,OAAsB;AACtD,cAAQ,EAAE,MAAM,MAAM;AAAA,IACvB;AAAA,IACA,QAAQ;AACP,cAAQ,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACnC;AAAA,IACA,MAAM,OAAO;AACZ,UAAI;AACH,cAAM,OAAO,MAAM,OAAO,IAAoD,oBAAoB;AAClG,gBAAQ,EAAE,GAAG,OAAO,KAAK;AAAA,MAC1B,QAAQ;AAAA,MAAsB;AAAA,IAC/B;AAAA,EACD;AACD;","names":["fetch"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/runes.svelte.ts"],"sourcesContent":["// Re-exports for non-Svelte consumers (bundled by tsup).\n// Implementation lives in runes.svelte.ts so Svelte's compiler handles\n// $state runes natively via the \"svelte\" export condition.\nexport {\n createCmsClient,\n createAsyncStore,\n createMutation,\n createAuthStore,\n type SvelteCmsConfig,\n type AsyncStore,\n type AuthState,\n type AuthStore,\n} from \"./runes.svelte.js\";\n","import { createClient, type HttpClient } from \"@lyeve-labs/client\";\n\n// Client factory\n\nexport interface SvelteCmsConfig {\n /** Base URL prepended to every request path. */\n baseUrl?: string;\n /**\n * Callback returning headers added to every request.\n * Called on every request so auth tokens can be refreshed without\n * recreating the client.\n */\n getHeaders?: () => Record<string, string>;\n}\n\n/**\n * Creates an HttpClient pre-configured with base URL and dynamic request\n * headers. No Provider needed - Svelte callers just pass the client around.\n *\n * @example\n * ```ts\n * const client = createCmsClient({\n * baseUrl: 'https://cms.example.com',\n * getHeaders: () => ({ Authorization: `Bearer ${token}` }),\n * });\n * ```\n */\nexport function createCmsClient(config: SvelteCmsConfig): HttpClient {\n const base = config.baseUrl ?? \"\";\n return createClient((url, init) => {\n const fullUrl = typeof url === \"string\" ? `${base}${url}` : url;\n return fetch(fullUrl, {\n ...init,\n headers: { ...init?.headers, ...config.getHeaders?.() },\n });\n });\n}\n\n// Generic async store\n\nexport interface AsyncStore<T> {\n readonly data: T | null;\n readonly error: Error | null;\n readonly loading: boolean;\n refetch: () => void;\n}\n\n/**\n * Reactive async data store using the $state rune.\n * Fires the fetcher immediately and exposes reactive loading/data/error\n * getters that Svelte components can read directly in markup.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const schemas = createAsyncStore((c) => getSchemas(c), client);\n * </script>\n * {#if schemas.loading}...{/if}\n * ```\n */\nexport function createAsyncStore<T>(\n fetcher: (client: HttpClient) => Promise<T>,\n client: HttpClient,\n): AsyncStore<T> {\n let data = $state<T | null>(null);\n let error = $state<Error | null>(null);\n let loading = $state(true);\n\n async function fetch() {\n loading = true;\n try {\n data = await fetcher(client);\n error = null;\n } catch (e) {\n error = e as Error;\n } finally {\n loading = false;\n }\n }\n\n fetch();\n\n return {\n get data() {\n return data;\n },\n get error() {\n return error;\n },\n get loading() {\n return loading;\n },\n refetch: fetch,\n };\n}\n\n/**\n * Reactive mutation primitive using the $state rune.\n * Returns data/error/loading state and a run function that triggers the\n * mutation. Unlike createAsyncStore, the mutation does not fire immediately.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const createArticle = createMutation(\n * (c, vars: { title: string }) => createArticle(c, vars),\n * client,\n * );\n * </script>\n * <button onclick={() => createArticle.run({ title: 'Hello' })}>\n * {createArticle.loading ? 'Saving...' : 'Create'}\n * </button>\n * ```\n */\nexport function createMutation<T, V>(\n mutator: (client: HttpClient, vars: V) => Promise<T>,\n client: HttpClient,\n) {\n let data = $state<T | null>(null);\n let error = $state<Error | null>(null);\n let loading = $state(false);\n\n async function run(vars: V): Promise<T> {\n loading = true;\n error = null;\n try {\n const result = await mutator(client, vars);\n data = result;\n return result;\n } catch (e) {\n error = e as Error;\n throw e;\n } finally {\n loading = false;\n }\n }\n\n return {\n get data() {\n return data;\n },\n get error() {\n return error;\n },\n get loading() {\n return loading;\n },\n run,\n };\n}\n\n// Auth store\n\nexport interface AuthState {\n user: { id: string; email: string; roles: string[] } | null;\n token: string | null;\n}\n\nexport interface AuthStore {\n readonly user: AuthState[\"user\"];\n readonly token: string | null;\n readonly isAuthenticated: boolean;\n /** Set the current user and token after a successful login. */\n setUser: (user: AuthState[\"user\"], token: string | null) => void;\n /** Clear auth state (e.g. after logout). */\n clear: () => void;\n /** Try to load the current user from the server using the stored token. */\n load: () => Promise<void>;\n}\n\n/**\n * Simple reactive auth store. The caller is responsible for calling\n * {@link AuthStore.setUser} after login and {@link AuthStore.clear} after\n * logout. Use {@link AuthStore.load} on app start to restore a session\n * from an existing cookie.\n */\nexport function createAuthStore(client: HttpClient): AuthStore {\n let state = $state<AuthState>({ user: null, token: null });\n\n return {\n get user() {\n return state.user;\n },\n get token() {\n return state.token;\n },\n get isAuthenticated() {\n return state.token !== null;\n },\n setUser(user: AuthState[\"user\"], token: string | null) {\n state = { user, token };\n },\n clear() {\n state = { user: null, token: null };\n },\n async load() {\n try {\n const user = await client.get<{\n id: string;\n email: string;\n roles: string[];\n }>(\"/api/admin/auth/me\");\n state = { ...state, user };\n } catch {\n /* not logged in */\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA8C;AA2BvC,SAAS,gBAAgB,QAAqC;AACnE,QAAM,OAAO,OAAO,WAAW;AAC/B,aAAO,4BAAa,CAAC,KAAK,SAAS;AACjC,UAAM,UAAU,OAAO,QAAQ,WAAW,GAAG,IAAI,GAAG,GAAG,KAAK;AAC5D,WAAO,MAAM,SAAS;AAAA,MACpB,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,MAAM,SAAS,GAAG,OAAO,aAAa,EAAE;AAAA,IACxD,CAAC;AAAA,EACH,CAAC;AACH;AAwBO,SAAS,iBACd,SACA,QACe;AACf,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,IAAI;AAEzB,iBAAeA,SAAQ;AACrB,cAAU;AACV,QAAI;AACF,aAAO,MAAM,QAAQ,MAAM;AAC3B,cAAQ;AAAA,IACV,SAAS,GAAG;AACV,cAAQ;AAAA,IACV,UAAE;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,EAAAA,OAAM;AAEN,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA,SAASA;AAAA,EACX;AACF;AAoBO,SAAS,eACd,SACA,QACA;AACA,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,KAAK;AAE1B,iBAAe,IAAI,MAAqB;AACtC,cAAU;AACV,YAAQ;AACR,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI;AACzC,aAAO;AACP,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ;AACR,YAAM;AAAA,IACR,UAAE;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AA2BO,SAAS,gBAAgB,QAA+B;AAC7D,MAAI,QAAQ,OAAkB,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC;AAEzD,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,QAAQ;AACV,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,kBAAkB;AACpB,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,QAAQ,MAAyB,OAAsB;AACrD,cAAQ,EAAE,MAAM,MAAM;AAAA,IACxB;AAAA,IACA,QAAQ;AACN,cAAQ,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACpC;AAAA,IACA,MAAM,OAAO;AACX,UAAI;AACF,cAAM,OAAO,MAAM,OAAO,IAIvB,oBAAoB;AACvB,gBAAQ,EAAE,GAAG,OAAO,KAAK;AAAA,MAC3B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;","names":["fetch"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpClient } from '@lyeve/cms-client';
1
+ import { HttpClient } from '@lyeve-labs/client';
2
2
 
3
3
  interface SvelteCmsConfig {
4
4
  /** Base URL prepended to every request path. */
@@ -76,11 +76,11 @@ interface AuthState {
76
76
  token: string | null;
77
77
  }
78
78
  interface AuthStore {
79
- readonly user: AuthState['user'];
79
+ readonly user: AuthState["user"];
80
80
  readonly token: string | null;
81
81
  readonly isAuthenticated: boolean;
82
82
  /** Set the current user and token after a successful login. */
83
- setUser: (user: AuthState['user'], token: string | null) => void;
83
+ setUser: (user: AuthState["user"], token: string | null) => void;
84
84
  /** Clear auth state (e.g. after logout). */
85
85
  clear: () => void;
86
86
  /** Try to load the current user from the server using the stored token. */
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpClient } from '@lyeve/cms-client';
1
+ import { HttpClient } from '@lyeve-labs/client';
2
2
 
3
3
  interface SvelteCmsConfig {
4
4
  /** Base URL prepended to every request path. */
@@ -76,11 +76,11 @@ interface AuthState {
76
76
  token: string | null;
77
77
  }
78
78
  interface AuthStore {
79
- readonly user: AuthState['user'];
79
+ readonly user: AuthState["user"];
80
80
  readonly token: string | null;
81
81
  readonly isAuthenticated: boolean;
82
82
  /** Set the current user and token after a successful login. */
83
- setUser: (user: AuthState['user'], token: string | null) => void;
83
+ setUser: (user: AuthState["user"], token: string | null) => void;
84
84
  /** Clear auth state (e.g. after logout). */
85
85
  clear: () => void;
86
86
  /** Try to load the current user from the server using the stored token. */
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- // src/runes.ts
2
- import { createClient } from "@lyeve/cms-client";
1
+ // src/runes.svelte.ts
2
+ import { createClient } from "@lyeve-labs/client";
3
3
  function createCmsClient(config) {
4
4
  const base = config.baseUrl ?? "";
5
5
  return createClient((url, init) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runes.ts"],"sourcesContent":["import { createClient, type HttpClient } from '@lyeve/cms-client';\n\n// Client factory\n\nexport interface SvelteCmsConfig {\n\t/** Base URL prepended to every request path. */\n\tbaseUrl?: string;\n\t/**\n\t * Callback returning headers added to every request.\n\t * Called on every request so auth tokens can be refreshed without\n\t * recreating the client.\n\t */\n\tgetHeaders?: () => Record<string, string>;\n}\n\n/**\n * Creates an HttpClient pre-configured with base URL and dynamic request\n * headers. No Provider needed - Svelte callers just pass the client around.\n *\n * @example\n * ```ts\n * const client = createCmsClient({\n * baseUrl: 'https://cms.example.com',\n * getHeaders: () => ({ Authorization: `Bearer ${token}` }),\n * });\n * ```\n */\nexport function createCmsClient(config: SvelteCmsConfig): HttpClient {\n\tconst base = config.baseUrl ?? '';\n\treturn createClient((url, init) => {\n\t\tconst fullUrl = typeof url === 'string' ? `${base}${url}` : url;\n\t\treturn fetch(fullUrl, {\n\t\t\t...init,\n\t\t\theaders: { ...init?.headers, ...config.getHeaders?.() },\n\t\t});\n\t});\n}\n\n// Generic async store\n\nexport interface AsyncStore<T> {\n\treadonly data: T | null;\n\treadonly error: Error | null;\n\treadonly loading: boolean;\n\trefetch: () => void;\n}\n\n/**\n * Reactive async data store using the $state rune.\n * Fires the fetcher immediately and exposes reactive loading/data/error\n * getters that Svelte components can read directly in markup.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const schemas = createAsyncStore((c) => getSchemas(c), client);\n * </script>\n * {#if schemas.loading}...{/if}\n * ```\n */\nexport function createAsyncStore<T>(\n\tfetcher: (client: HttpClient) => Promise<T>,\n\tclient: HttpClient,\n): AsyncStore<T> {\n\tlet data = $state<T | null>(null);\n\tlet error = $state<Error | null>(null);\n\tlet loading = $state(true);\n\n\tasync function fetch() {\n\t\tloading = true;\n\t\ttry {\n\t\t\tdata = await fetcher(client);\n\t\t\terror = null;\n\t\t} catch (e) {\n\t\t\terror = e as Error;\n\t\t} finally {\n\t\t\tloading = false;\n\t\t}\n\t}\n\n\tfetch();\n\n\treturn {\n\t\tget data() { return data; },\n\t\tget error() { return error; },\n\t\tget loading() { return loading; },\n\t\trefetch: fetch,\n\t};\n}\n\n/**\n * Reactive mutation primitive using the $state rune.\n * Returns data/error/loading state and a run function that triggers the\n * mutation. Unlike createAsyncStore, the mutation does not fire immediately.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const createArticle = createMutation(\n * (c, vars: { title: string }) => createArticle(c, vars),\n * client,\n * );\n * </script>\n * <button onclick={() => createArticle.run({ title: 'Hello' })}>\n * {createArticle.loading ? 'Saving...' : 'Create'}\n * </button>\n * ```\n */\nexport function createMutation<T, V>(\n\tmutator: (client: HttpClient, vars: V) => Promise<T>,\n\tclient: HttpClient,\n) {\n\tlet data = $state<T | null>(null);\n\tlet error = $state<Error | null>(null);\n\tlet loading = $state(false);\n\n\tasync function run(vars: V): Promise<T> {\n\t\tloading = true;\n\t\terror = null;\n\t\ttry {\n\t\t\tconst result = await mutator(client, vars);\n\t\t\tdata = result;\n\t\t\treturn result;\n\t\t} catch (e) {\n\t\t\terror = e as Error;\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tloading = false;\n\t\t}\n\t}\n\n\treturn {\n\t\tget data() { return data; },\n\t\tget error() { return error; },\n\t\tget loading() { return loading; },\n\t\trun,\n\t};\n}\n\n// Auth store\n\nexport interface AuthState {\n\tuser: { id: string; email: string; roles: string[] } | null;\n\ttoken: string | null;\n}\n\nexport interface AuthStore {\n\treadonly user: AuthState['user'];\n\treadonly token: string | null;\n\treadonly isAuthenticated: boolean;\n\t/** Set the current user and token after a successful login. */\n\tsetUser: (user: AuthState['user'], token: string | null) => void;\n\t/** Clear auth state (e.g. after logout). */\n\tclear: () => void;\n\t/** Try to load the current user from the server using the stored token. */\n\tload: () => Promise<void>;\n}\n\n/**\n * Simple reactive auth store. The caller is responsible for calling\n * {@link AuthStore.setUser} after login and {@link AuthStore.clear} after\n * logout. Use {@link AuthStore.load} on app start to restore a session\n * from an existing cookie.\n */\nexport function createAuthStore(client: HttpClient): AuthStore {\n\tlet state = $state<AuthState>({ user: null, token: null });\n\n\treturn {\n\t\tget user() { return state.user; },\n\t\tget token() { return state.token; },\n\t\tget isAuthenticated() { return state.token !== null; },\n\t\tsetUser(user: AuthState['user'], token: string | null) {\n\t\t\tstate = { user, token };\n\t\t},\n\t\tclear() {\n\t\t\tstate = { user: null, token: null };\n\t\t},\n\t\tasync load() {\n\t\t\ttry {\n\t\t\t\tconst user = await client.get<{ id: string; email: string; roles: string[] }>('/api/admin/auth/me');\n\t\t\t\tstate = { ...state, user };\n\t\t\t} catch { /* not logged in */ }\n\t\t},\n\t};\n}\n"],"mappings":";AAAA,SAAS,oBAAqC;AA2BvC,SAAS,gBAAgB,QAAqC;AACpE,QAAM,OAAO,OAAO,WAAW;AAC/B,SAAO,aAAa,CAAC,KAAK,SAAS;AAClC,UAAM,UAAU,OAAO,QAAQ,WAAW,GAAG,IAAI,GAAG,GAAG,KAAK;AAC5D,WAAO,MAAM,SAAS;AAAA,MACrB,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,MAAM,SAAS,GAAG,OAAO,aAAa,EAAE;AAAA,IACvD,CAAC;AAAA,EACF,CAAC;AACF;AAwBO,SAAS,iBACf,SACA,QACgB;AAChB,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,IAAI;AAEzB,iBAAeA,SAAQ;AACtB,cAAU;AACV,QAAI;AACH,aAAO,MAAM,QAAQ,MAAM;AAC3B,cAAQ;AAAA,IACT,SAAS,GAAG;AACX,cAAQ;AAAA,IACT,UAAE;AACD,gBAAU;AAAA,IACX;AAAA,EACD;AAEA,EAAAA,OAAM;AAEN,SAAO;AAAA,IACN,IAAI,OAAO;AAAE,aAAO;AAAA,IAAM;AAAA,IAC1B,IAAI,QAAQ;AAAE,aAAO;AAAA,IAAO;AAAA,IAC5B,IAAI,UAAU;AAAE,aAAO;AAAA,IAAS;AAAA,IAChC,SAASA;AAAA,EACV;AACD;AAoBO,SAAS,eACf,SACA,QACC;AACD,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,KAAK;AAE1B,iBAAe,IAAI,MAAqB;AACvC,cAAU;AACV,YAAQ;AACR,QAAI;AACH,YAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI;AACzC,aAAO;AACP,aAAO;AAAA,IACR,SAAS,GAAG;AACX,cAAQ;AACR,YAAM;AAAA,IACP,UAAE;AACD,gBAAU;AAAA,IACX;AAAA,EACD;AAEA,SAAO;AAAA,IACN,IAAI,OAAO;AAAE,aAAO;AAAA,IAAM;AAAA,IAC1B,IAAI,QAAQ;AAAE,aAAO;AAAA,IAAO;AAAA,IAC5B,IAAI,UAAU;AAAE,aAAO;AAAA,IAAS;AAAA,IAChC;AAAA,EACD;AACD;AA2BO,SAAS,gBAAgB,QAA+B;AAC9D,MAAI,QAAQ,OAAkB,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC;AAEzD,SAAO;AAAA,IACN,IAAI,OAAO;AAAE,aAAO,MAAM;AAAA,IAAM;AAAA,IAChC,IAAI,QAAQ;AAAE,aAAO,MAAM;AAAA,IAAO;AAAA,IAClC,IAAI,kBAAkB;AAAE,aAAO,MAAM,UAAU;AAAA,IAAM;AAAA,IACrD,QAAQ,MAAyB,OAAsB;AACtD,cAAQ,EAAE,MAAM,MAAM;AAAA,IACvB;AAAA,IACA,QAAQ;AACP,cAAQ,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACnC;AAAA,IACA,MAAM,OAAO;AACZ,UAAI;AACH,cAAM,OAAO,MAAM,OAAO,IAAoD,oBAAoB;AAClG,gBAAQ,EAAE,GAAG,OAAO,KAAK;AAAA,MAC1B,QAAQ;AAAA,MAAsB;AAAA,IAC/B;AAAA,EACD;AACD;","names":["fetch"]}
1
+ {"version":3,"sources":["../src/runes.svelte.ts"],"sourcesContent":["import { createClient, type HttpClient } from \"@lyeve-labs/client\";\n\n// Client factory\n\nexport interface SvelteCmsConfig {\n /** Base URL prepended to every request path. */\n baseUrl?: string;\n /**\n * Callback returning headers added to every request.\n * Called on every request so auth tokens can be refreshed without\n * recreating the client.\n */\n getHeaders?: () => Record<string, string>;\n}\n\n/**\n * Creates an HttpClient pre-configured with base URL and dynamic request\n * headers. No Provider needed - Svelte callers just pass the client around.\n *\n * @example\n * ```ts\n * const client = createCmsClient({\n * baseUrl: 'https://cms.example.com',\n * getHeaders: () => ({ Authorization: `Bearer ${token}` }),\n * });\n * ```\n */\nexport function createCmsClient(config: SvelteCmsConfig): HttpClient {\n const base = config.baseUrl ?? \"\";\n return createClient((url, init) => {\n const fullUrl = typeof url === \"string\" ? `${base}${url}` : url;\n return fetch(fullUrl, {\n ...init,\n headers: { ...init?.headers, ...config.getHeaders?.() },\n });\n });\n}\n\n// Generic async store\n\nexport interface AsyncStore<T> {\n readonly data: T | null;\n readonly error: Error | null;\n readonly loading: boolean;\n refetch: () => void;\n}\n\n/**\n * Reactive async data store using the $state rune.\n * Fires the fetcher immediately and exposes reactive loading/data/error\n * getters that Svelte components can read directly in markup.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const schemas = createAsyncStore((c) => getSchemas(c), client);\n * </script>\n * {#if schemas.loading}...{/if}\n * ```\n */\nexport function createAsyncStore<T>(\n fetcher: (client: HttpClient) => Promise<T>,\n client: HttpClient,\n): AsyncStore<T> {\n let data = $state<T | null>(null);\n let error = $state<Error | null>(null);\n let loading = $state(true);\n\n async function fetch() {\n loading = true;\n try {\n data = await fetcher(client);\n error = null;\n } catch (e) {\n error = e as Error;\n } finally {\n loading = false;\n }\n }\n\n fetch();\n\n return {\n get data() {\n return data;\n },\n get error() {\n return error;\n },\n get loading() {\n return loading;\n },\n refetch: fetch,\n };\n}\n\n/**\n * Reactive mutation primitive using the $state rune.\n * Returns data/error/loading state and a run function that triggers the\n * mutation. Unlike createAsyncStore, the mutation does not fire immediately.\n *\n * @example\n * ```svelte\n * <script lang=\"ts\">\n * const createArticle = createMutation(\n * (c, vars: { title: string }) => createArticle(c, vars),\n * client,\n * );\n * </script>\n * <button onclick={() => createArticle.run({ title: 'Hello' })}>\n * {createArticle.loading ? 'Saving...' : 'Create'}\n * </button>\n * ```\n */\nexport function createMutation<T, V>(\n mutator: (client: HttpClient, vars: V) => Promise<T>,\n client: HttpClient,\n) {\n let data = $state<T | null>(null);\n let error = $state<Error | null>(null);\n let loading = $state(false);\n\n async function run(vars: V): Promise<T> {\n loading = true;\n error = null;\n try {\n const result = await mutator(client, vars);\n data = result;\n return result;\n } catch (e) {\n error = e as Error;\n throw e;\n } finally {\n loading = false;\n }\n }\n\n return {\n get data() {\n return data;\n },\n get error() {\n return error;\n },\n get loading() {\n return loading;\n },\n run,\n };\n}\n\n// Auth store\n\nexport interface AuthState {\n user: { id: string; email: string; roles: string[] } | null;\n token: string | null;\n}\n\nexport interface AuthStore {\n readonly user: AuthState[\"user\"];\n readonly token: string | null;\n readonly isAuthenticated: boolean;\n /** Set the current user and token after a successful login. */\n setUser: (user: AuthState[\"user\"], token: string | null) => void;\n /** Clear auth state (e.g. after logout). */\n clear: () => void;\n /** Try to load the current user from the server using the stored token. */\n load: () => Promise<void>;\n}\n\n/**\n * Simple reactive auth store. The caller is responsible for calling\n * {@link AuthStore.setUser} after login and {@link AuthStore.clear} after\n * logout. Use {@link AuthStore.load} on app start to restore a session\n * from an existing cookie.\n */\nexport function createAuthStore(client: HttpClient): AuthStore {\n let state = $state<AuthState>({ user: null, token: null });\n\n return {\n get user() {\n return state.user;\n },\n get token() {\n return state.token;\n },\n get isAuthenticated() {\n return state.token !== null;\n },\n setUser(user: AuthState[\"user\"], token: string | null) {\n state = { user, token };\n },\n clear() {\n state = { user: null, token: null };\n },\n async load() {\n try {\n const user = await client.get<{\n id: string;\n email: string;\n roles: string[];\n }>(\"/api/admin/auth/me\");\n state = { ...state, user };\n } catch {\n /* not logged in */\n }\n },\n };\n}\n"],"mappings":";AAAA,SAAS,oBAAqC;AA2BvC,SAAS,gBAAgB,QAAqC;AACnE,QAAM,OAAO,OAAO,WAAW;AAC/B,SAAO,aAAa,CAAC,KAAK,SAAS;AACjC,UAAM,UAAU,OAAO,QAAQ,WAAW,GAAG,IAAI,GAAG,GAAG,KAAK;AAC5D,WAAO,MAAM,SAAS;AAAA,MACpB,GAAG;AAAA,MACH,SAAS,EAAE,GAAG,MAAM,SAAS,GAAG,OAAO,aAAa,EAAE;AAAA,IACxD,CAAC;AAAA,EACH,CAAC;AACH;AAwBO,SAAS,iBACd,SACA,QACe;AACf,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,IAAI;AAEzB,iBAAeA,SAAQ;AACrB,cAAU;AACV,QAAI;AACF,aAAO,MAAM,QAAQ,MAAM;AAC3B,cAAQ;AAAA,IACV,SAAS,GAAG;AACV,cAAQ;AAAA,IACV,UAAE;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,EAAAA,OAAM;AAEN,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA,SAASA;AAAA,EACX;AACF;AAoBO,SAAS,eACd,SACA,QACA;AACA,MAAI,OAAO,OAAiB,IAAI;AAChC,MAAI,QAAQ,OAAqB,IAAI;AACrC,MAAI,UAAU,OAAO,KAAK;AAE1B,iBAAe,IAAI,MAAqB;AACtC,cAAU;AACV,YAAQ;AACR,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI;AACzC,aAAO;AACP,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ;AACR,YAAM;AAAA,IACR,UAAE;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AA2BO,SAAS,gBAAgB,QAA+B;AAC7D,MAAI,QAAQ,OAAkB,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC;AAEzD,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,QAAQ;AACV,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,kBAAkB;AACpB,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,QAAQ,MAAyB,OAAsB;AACrD,cAAQ,EAAE,MAAM,MAAM;AAAA,IACxB;AAAA,IACA,QAAQ;AACN,cAAQ,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACpC;AAAA,IACA,MAAM,OAAO;AACX,UAAI;AACF,cAAM,OAAO,MAAM,OAAO,IAIvB,oBAAoB;AACvB,gBAAQ,EAAE,GAAG,OAAO,KAAK;AAAA,MAC3B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;","names":["fetch"]}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@lyeve-labs/client-svelte",
3
- "version": "0.1.2",
4
- "description": "Svelte 5 reactive stores for the LyEve Core API - thin wrapper around @lyeve/cms-client using $state runes",
3
+ "version": "0.1.3",
4
+ "description": "Svelte 5 reactive stores for the LyEve Core API - thin wrapper around @lyeve-labs/client using $state runes",
5
5
  "license": "MIT",
6
- "author": "LyEve Labs <hello@lyeve.com>",
6
+ "author": "LyEve <info@lyeve.com>",
7
7
  "type": "module",
8
+ "packageManager": "pnpm@9.15.0",
8
9
  "engines": {
9
10
  "node": ">=20"
10
11
  },
@@ -15,9 +16,14 @@
15
16
  "exports": {
16
17
  ".": {
17
18
  "svelte": "./src/index.svelte.ts",
18
- "types": "./dist/index.d.ts",
19
- "import": "./dist/index.js",
20
- "require": "./dist/index.cjs"
19
+ "import": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "require": {
24
+ "types": "./dist/index.d.cts",
25
+ "default": "./dist/index.cjs"
26
+ }
21
27
  },
22
28
  "./package.json": "./package.json"
23
29
  },
@@ -30,26 +36,26 @@
30
36
  "publishConfig": {
31
37
  "access": "public"
32
38
  },
39
+ "scripts": {
40
+ "dev": "tsup --watch",
41
+ "build": "tsup && publint && node scripts/check-dist.mjs",
42
+ "check": "tsc --noEmit",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "format": "prettier --write .",
46
+ "format:check": "prettier --check ."
47
+ },
33
48
  "peerDependencies": {
34
- "@lyeve-labs/client-svelte": ">=0.1.0",
49
+ "@lyeve-labs/client": ">=0.1.0",
35
50
  "svelte": ">=5.0.0"
36
51
  },
37
52
  "devDependencies": {
38
- "@lyeve-labs/client-svelte": "^0.1.0",
53
+ "@lyeve-labs/client": "^0.2.0",
39
54
  "svelte": "^5.0.0",
40
55
  "tsup": "^8.4.0",
41
56
  "typescript": "^5.7.0",
42
57
  "vitest": "^2.1.0",
43
58
  "publint": "^0.3.0",
44
59
  "prettier": "^3.4.0"
45
- },
46
- "scripts": {
47
- "dev": "tsup --watch",
48
- "build": "tsup && publint",
49
- "check": "tsc --noEmit",
50
- "test": "vitest run",
51
- "test:watch": "vitest",
52
- "format": "prettier --write .",
53
- "format:check": "prettier --check ."
54
60
  }
55
- }
61
+ }