@templatical/core 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,10 +50,12 @@ watch(editor.content, (next) => {
50
50
  - `useAutoSave` — debounced save with onSave callback
51
51
  - `useConditionPreview` — display condition preview state
52
52
  - `useDataSourceFetch` — fetch helper for custom block data sources
53
+ - `useSavedBlocks` — reactive list/create/update/remove over a `SavedBlocksProvider` (saved blocks)
54
+ - `createLocalStorageSavedBlocksProvider` — bundled browser-local `SavedBlocksProvider`, for demos and prototypes
53
55
 
54
56
  ## Cloud subpath
55
57
 
56
- The `@templatical/core/cloud` subpath provides Templatical Cloud integrations (Auth, API client, WebSocket, AI chat/rewrite, collaboration, comments, scoring). Used by `@templatical/editor`'s `initCloud()`. See [Cloud docs](https://docs.templatical.com/cloud/).
58
+ The `@templatical/core/cloud` subpath provides Templatical Cloud integrations (Auth, API client, WebSocket, AI chat/rewrite, collaboration, comments, scoring, and `createCloudSavedBlocksProvider`). Used by `@templatical/editor`'s `initCloud()`. See [Cloud docs](https://docs.templatical.com/cloud/).
57
59
 
58
60
  ## Documentation
59
61
 
@@ -1,5 +1,5 @@
1
1
  import { r as UseEditorReturn$1 } from "../editor-BIIsaIoN.js";
2
- import { AiChatMessage, AiConfig, AuthConfig, AuthRequestOptions, Block, Collaborator, Comment, CommentEvent, CommentThread, CustomFont, EditorState, ExportResult, FontsConfig, HealthCheckResult, McpOperationPayload, MergeTag, PlanConfig, PlanFeatures, SavedModule, ScoringCategory, ScoringFinding, ScoringResult, SdkAuthConfig, Template, TemplateContent, TemplateDefaults, TemplateSettings, TemplateSnapshot, TestEmailConfig, UiTheme, UserConfig, ViewportSize, WebSocketServerConfig } from "@templatical/types";
2
+ import { AiChatMessage, AiConfig, AuthConfig, AuthRequestOptions, Block, Collaborator, Comment, CommentEvent, CommentThread, CustomFont, EditorState, ExportResult, FontsConfig, HealthCheckResult, McpOperationPayload, MergeTag, PlanConfig, PlanFeatures, SavedBlock, SavedBlocksProvider, ScoringCategory, ScoringFinding, ScoringResult, SdkAuthConfig, Template, TemplateContent, TemplateDefaults, TemplateSettings, TemplateSnapshot, TestEmailConfig, UiTheme, UserConfig, ViewportSize, WebSocketServerConfig } from "@templatical/types";
3
3
  import { ComputedRef, DeepReadonly, Ref, ref } from "vue";
4
4
  import { Channel, PresenceChannel } from "pusher-js";
5
5
  //#region src/cloud/auth.d.ts
@@ -91,15 +91,17 @@ declare class ApiClient {
91
91
  user_signature: string;
92
92
  }, headers?: Record<string, string>): Promise<Comment>;
93
93
  fetchConfig(): Promise<PlanConfig>;
94
- listModules(search?: string): Promise<SavedModule[]>;
94
+ listModules(search?: string, category?: string): Promise<SavedBlock[]>;
95
95
  createModule(data: {
96
96
  name: string;
97
97
  content: Block[];
98
- }): Promise<SavedModule>;
98
+ category?: string;
99
+ }): Promise<SavedBlock>;
99
100
  updateModule(id: string, data: Partial<{
100
101
  name: string;
101
102
  content: Block[];
102
- }>): Promise<SavedModule>;
103
+ category: string;
104
+ }>): Promise<SavedBlock>;
103
105
  deleteModule(id: string): Promise<void>;
104
106
  }
105
107
  //#endregion
@@ -408,23 +410,27 @@ interface UseWebSocketReturn {
408
410
  }
409
411
  declare function useWebSocket(options: UseWebSocketOptions): UseWebSocketReturn;
410
412
  //#endregion
411
- //#region src/cloud/saved-modules.d.ts
412
- interface UseSavedModulesOptions {
413
- authManager: AuthManager;
414
- onError?: (error: Error) => void;
415
- }
416
- interface UseSavedModulesReturn {
417
- modules: Ref<SavedModule[]>;
418
- isLoading: Ref<boolean>;
419
- loadModules: (search?: string) => Promise<void>;
420
- createModule: (name: string, content: Block[]) => Promise<SavedModule>;
421
- updateModule: (id: string, data: Partial<{
422
- name: string;
423
- content: Block[];
424
- }>) => Promise<SavedModule>;
425
- deleteModule: (id: string) => Promise<void>;
426
- }
427
- declare function useSavedModules(options: UseSavedModulesOptions): UseSavedModulesReturn;
413
+ //#region src/cloud/saved-blocks-provider.d.ts
414
+ /**
415
+ * Cloud-backed {@link SavedBlocksProvider} — the Templatical Cloud adapter for
416
+ * the same contract consumers implement themselves.
417
+ *
418
+ * Auth (JWT via {@link AuthManager}) and project/tenant scoping live entirely
419
+ * on this side of the seam: the shared `useSavedBlocks` composable and the
420
+ * editor UI never see them. Plan gating is applied by the caller before this
421
+ * provider is constructed.
422
+ *
423
+ * Wraps the existing `ApiClient` saved-module endpoints, so the REST contract
424
+ * is unchanged from before saved blocks became an open-source feature.
425
+ *
426
+ * Rows pass straight through, unmapped: the Cloud endpoints speak the same
427
+ * `SavedBlock` shape the contract defines, so this adapter only supplies auth
428
+ * and scoping. That means the payload's field names track the contract — the
429
+ * backend serialises `category`, `canUpdate`, `canDelete`, `createdAt` and
430
+ * `updatedAt`. Until it does, those fields simply arrive absent, which degrades
431
+ * to "no timestamp label, every action allowed" rather than breaking.
432
+ */
433
+ declare function createCloudSavedBlocksProvider(authManager: AuthManager): SavedBlocksProvider;
428
434
  //#endregion
429
435
  //#region src/cloud/snapshots.d.ts
430
436
  interface UseSnapshotHistoryOptions {
@@ -502,5 +508,5 @@ interface UseMcpListenerOptions {
502
508
  }
503
509
  declare function useMcpListener(options: UseMcpListenerOptions): void;
504
510
  //#endregion
505
- export { API_ROUTES, ApiClient, type AuthConfig, AuthManager, type AuthRequestOptions, type CommentBroadcastPayload, type DesignReferenceInput, type PresenceMember, type SdkAuthConfig, type TestEmailConfig, type UseAiChatOptions, type UseAiChatReturn, type UseAiConfigReturn, type UseAiRewriteOptions, type UseAiRewriteReturn, type UseCollaborationOptions, type UseCollaborationReturn, type UseCommentListenerOptions, type UseCommentsOptions, type UseCommentsReturn, type UseDesignReferenceOptions, type UseDesignReferenceReturn, type UseEditorOptions, type UseEditorReturn, type UseExportOptions, type UseExportReturn, type UseMcpListenerOptions, type UsePlanConfigOptions, type UsePlanConfigReturn, type UseSavedModulesOptions, type UseSavedModulesReturn, type UseSnapshotHistoryOptions, type UseSnapshotHistoryReturn, type UseTemplateScoringOptions, type UseTemplateScoringReturn, type UseTestEmailOptions, type UseTestEmailReturn, type UseWebSocketOptions, type UseWebSocketReturn, type UserConfig, WebSocketClient, type WebSocketClientOptions, type WebSocketConfig, buildUrl, createSdkAuthManager, handleOperation, performHealthCheck, resolveWebSocketConfig, useAiChat, useAiConfig, useAiRewrite, useCollaboration, useCollaborationBroadcast, useCommentListener, useComments, useDesignReference, useEditor, useExport, useMcpListener, usePlanConfig, useSavedModules, useSnapshotHistory, useTemplateScoring, useTestEmail, useWebSocket };
511
+ export { API_ROUTES, ApiClient, type AuthConfig, AuthManager, type AuthRequestOptions, type CommentBroadcastPayload, type DesignReferenceInput, type PresenceMember, type SdkAuthConfig, type TestEmailConfig, type UseAiChatOptions, type UseAiChatReturn, type UseAiConfigReturn, type UseAiRewriteOptions, type UseAiRewriteReturn, type UseCollaborationOptions, type UseCollaborationReturn, type UseCommentListenerOptions, type UseCommentsOptions, type UseCommentsReturn, type UseDesignReferenceOptions, type UseDesignReferenceReturn, type UseEditorOptions, type UseEditorReturn, type UseExportOptions, type UseExportReturn, type UseMcpListenerOptions, type UsePlanConfigOptions, type UsePlanConfigReturn, type UseSnapshotHistoryOptions, type UseSnapshotHistoryReturn, type UseTemplateScoringOptions, type UseTemplateScoringReturn, type UseTestEmailOptions, type UseTestEmailReturn, type UseWebSocketOptions, type UseWebSocketReturn, type UserConfig, WebSocketClient, type WebSocketClientOptions, type WebSocketConfig, buildUrl, createCloudSavedBlocksProvider, createSdkAuthManager, handleOperation, performHealthCheck, resolveWebSocketConfig, useAiChat, useAiConfig, useAiRewrite, useCollaboration, useCollaborationBroadcast, useCommentListener, useComments, useDesignReference, useEditor, useExport, useMcpListener, usePlanConfig, useSnapshotHistory, useTemplateScoring, useTestEmail, useWebSocket };
506
512
  //# sourceMappingURL=index.d.ts.map
@@ -368,9 +368,12 @@ var ApiClient = class {
368
368
  async fetchConfig() {
369
369
  return this.request(buildUrl(API_ROUTES["projects.config"], this.baseParams));
370
370
  }
371
- async listModules(search) {
371
+ async listModules(search, category) {
372
372
  const url = buildUrl(API_ROUTES["savedModules.index"], this.baseParams);
373
- const query = search ? `?search=${encodeURIComponent(search)}` : "";
373
+ const params = new URLSearchParams();
374
+ if (search) params.set("search", search);
375
+ if (category) params.set("category", category);
376
+ const query = params.size > 0 ? `?${params}` : "";
374
377
  return this.request(`${url}${query}`);
375
378
  }
376
379
  async createModule(data) {
@@ -1912,61 +1915,41 @@ function useWebSocket(options) {
1912
1915
  };
1913
1916
  }
1914
1917
  //#endregion
1915
- //#region src/cloud/saved-modules.ts
1916
- function useSavedModules(options) {
1917
- const api = new ApiClient(options.authManager);
1918
- const modules = ref([]);
1919
- const isLoading = ref(false);
1920
- async function loadModules(search) {
1921
- isLoading.value = true;
1922
- try {
1923
- modules.value = await api.listModules(search);
1924
- } catch (error) {
1925
- options.onError?.(error);
1926
- throw error;
1927
- } finally {
1928
- isLoading.value = false;
1929
- }
1930
- }
1931
- async function createModule(name, content) {
1932
- try {
1933
- const module = await api.createModule({
1934
- name,
1935
- content
1936
- });
1937
- modules.value = [module, ...modules.value];
1938
- return module;
1939
- } catch (error) {
1940
- options.onError?.(error);
1941
- throw error;
1942
- }
1943
- }
1944
- async function updateModule(id, data) {
1945
- try {
1946
- const updated = await api.updateModule(id, data);
1947
- modules.value = modules.value.map((m) => m.id === id ? updated : m);
1948
- return updated;
1949
- } catch (error) {
1950
- options.onError?.(error);
1951
- throw error;
1952
- }
1953
- }
1954
- async function deleteModule(id) {
1955
- try {
1956
- await api.deleteModule(id);
1957
- modules.value = modules.value.filter((m) => m.id !== id);
1958
- } catch (error) {
1959
- options.onError?.(error);
1960
- throw error;
1961
- }
1962
- }
1918
+ //#region src/cloud/saved-blocks-provider.ts
1919
+ /**
1920
+ * Cloud-backed {@link SavedBlocksProvider} — the Templatical Cloud adapter for
1921
+ * the same contract consumers implement themselves.
1922
+ *
1923
+ * Auth (JWT via {@link AuthManager}) and project/tenant scoping live entirely
1924
+ * on this side of the seam: the shared `useSavedBlocks` composable and the
1925
+ * editor UI never see them. Plan gating is applied by the caller before this
1926
+ * provider is constructed.
1927
+ *
1928
+ * Wraps the existing `ApiClient` saved-module endpoints, so the REST contract
1929
+ * is unchanged from before saved blocks became an open-source feature.
1930
+ *
1931
+ * Rows pass straight through, unmapped: the Cloud endpoints speak the same
1932
+ * `SavedBlock` shape the contract defines, so this adapter only supplies auth
1933
+ * and scoping. That means the payload's field names track the contract — the
1934
+ * backend serialises `category`, `canUpdate`, `canDelete`, `createdAt` and
1935
+ * `updatedAt`. Until it does, those fields simply arrive absent, which degrades
1936
+ * to "no timestamp label, every action allowed" rather than breaking.
1937
+ */
1938
+ function createCloudSavedBlocksProvider(authManager) {
1939
+ const api = new ApiClient(authManager);
1963
1940
  return {
1964
- modules,
1965
- isLoading,
1966
- loadModules,
1967
- createModule,
1968
- updateModule,
1969
- deleteModule
1941
+ list(params) {
1942
+ return api.listModules(params?.search, params?.category);
1943
+ },
1944
+ create(input) {
1945
+ return api.createModule(input);
1946
+ },
1947
+ update(id, patch) {
1948
+ return api.updateModule(id, patch);
1949
+ },
1950
+ delete(id) {
1951
+ return api.deleteModule(id);
1952
+ }
1970
1953
  };
1971
1954
  }
1972
1955
  //#endregion
@@ -2239,6 +2222,6 @@ function useMcpListener(options) {
2239
2222
  });
2240
2223
  }
2241
2224
  //#endregion
2242
- export { API_ROUTES, ApiClient, AuthManager, WebSocketClient, buildUrl, createSdkAuthManager, handleOperation, performHealthCheck, resolveWebSocketConfig, useAiChat, useAiConfig, useAiRewrite, useCollaboration, useCollaborationBroadcast, useCommentListener, useComments, useDesignReference, useEditor, useExport, useMcpListener, usePlanConfig, useSavedModules, useSnapshotHistory, useTemplateScoring, useTestEmail, useWebSocket };
2225
+ export { API_ROUTES, ApiClient, AuthManager, WebSocketClient, buildUrl, createCloudSavedBlocksProvider, createSdkAuthManager, handleOperation, performHealthCheck, resolveWebSocketConfig, useAiChat, useAiConfig, useAiRewrite, useCollaboration, useCollaborationBroadcast, useCommentListener, useComments, useDesignReference, useEditor, useExport, useMcpListener, usePlanConfig, useSnapshotHistory, useTemplateScoring, useTestEmail, useWebSocket };
2243
2226
 
2244
2227
  //# sourceMappingURL=index.js.map