@jchat/addon-sdk 1.0.0-alpha.30 → 1.0.0-alpha.31

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/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as hasPermission, a as useAddonSDK, c as useAddonInfiniteQuery, d as useQueryClient, f as AbilityBuilder, g as createMongoAbility, h as createAddonAbility, i as getAddonSdkVersion, l as useAddonMutation, m as authorizeResourceOwnership, n as defineAddonManifest, o as verifyAddonEntitlement, p as ForbiddenError, r as defineAddonServer, s as createMockAddonServerContext, t as AddonPipelineAbortError, u as useAddonQuery, v as subject } from "./src.mjs";
1
+ import { _ as createMongoAbility, a as useAddonSDK, c as useAddonInfiniteQuery, d as useAddonSettings, f as useQueryClient, g as createAddonAbility, h as authorizeResourceOwnership, i as getAddonSdkVersion, l as useAddonMutation, m as ForbiddenError, n as defineAddonManifest, o as verifyAddonEntitlement, p as AbilityBuilder, r as defineAddonServer, s as createMockAddonServerContext, t as AddonPipelineAbortError, u as useAddonQuery, v as hasPermission, y as subject } from "./src.mjs";
2
2
  import { HOST_LOCALES, MOUNT_POINTS } from "./contracts.mjs";
3
3
  import { i as useTranslation, n as createTranslator, r as useLocale, t as LocaleContext } from "./i18n.mjs";
4
4
  import { ADDON_ID_PATTERN, COMPATIBILITY_RANGE_PATTERN, MAX_ADDON_ARCHIVE_BYTES, assertSafeRelativePath, canonicalManifest, createCanonicalAddonDigest, isCompatibilityRange, sortValue, validateAddonManifest } from "./signing.mjs";
5
- export { ADDON_ID_PATTERN, AbilityBuilder, AddonPipelineAbortError, COMPATIBILITY_RANGE_PATTERN, ForbiddenError, HOST_LOCALES, LocaleContext, MAX_ADDON_ARCHIVE_BYTES, MOUNT_POINTS, assertSafeRelativePath, authorizeResourceOwnership, canonicalManifest, createAddonAbility, createCanonicalAddonDigest, createMockAddonServerContext, createMongoAbility, createTranslator, defineAddonManifest, defineAddonServer, getAddonSdkVersion, hasPermission, isCompatibilityRange, sortValue, subject, useAddonInfiniteQuery, useAddonMutation, useAddonQuery, useAddonSDK, useLocale, useQueryClient, useTranslation, validateAddonManifest, verifyAddonEntitlement };
5
+ export { ADDON_ID_PATTERN, AbilityBuilder, AddonPipelineAbortError, COMPATIBILITY_RANGE_PATTERN, ForbiddenError, HOST_LOCALES, LocaleContext, MAX_ADDON_ARCHIVE_BYTES, MOUNT_POINTS, assertSafeRelativePath, authorizeResourceOwnership, canonicalManifest, createAddonAbility, createCanonicalAddonDigest, createMockAddonServerContext, createMongoAbility, createTranslator, defineAddonManifest, defineAddonServer, getAddonSdkVersion, hasPermission, isCompatibilityRange, sortValue, subject, useAddonInfiniteQuery, useAddonMutation, useAddonQuery, useAddonSDK, useAddonSettings, useLocale, useQueryClient, useTranslation, validateAddonManifest, verifyAddonEntitlement };
package/dist/src.mjs CHANGED
@@ -2,7 +2,7 @@ import "./i18n.mjs";
2
2
  import { AbilityBuilder, createMongoAbility, subject } from "@casl/ability";
3
3
  import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
4
4
  //#region package.json
5
- var version = "1.0.0-alpha.30";
5
+ var version = "1.0.0-alpha.31";
6
6
  //#endregion
7
7
  //#region src/permissions.ts
8
8
  /**
@@ -192,6 +192,30 @@ function useAddonMutation(options) {
192
192
  }
193
193
  });
194
194
  }
195
+ /**
196
+ * Ergonomic hook for loading and updating site configuration for an addon. Handles fetching,
197
+ * caching, pending states, and automatic query cache invalidation.
198
+ */
199
+ function useAddonSettings(siteId) {
200
+ const sdk = useAddonSDK();
201
+ const query = useAddonQuery({
202
+ queryKey: ["settings", siteId],
203
+ queryFn: () => sdk.settings.get()
204
+ });
205
+ const mutation = useAddonMutation({
206
+ mutationFn: (settings) => sdk.settings.save(settings),
207
+ invalidateQueries: [["settings", siteId]]
208
+ });
209
+ return {
210
+ settings: query.data ?? null,
211
+ isLoading: query.isLoading,
212
+ isSaving: mutation.isPending,
213
+ error: query.error ?? mutation.error,
214
+ saveSettings: mutation.mutate,
215
+ saveSettingsAsync: mutation.mutateAsync,
216
+ refetch: query.refetch
217
+ };
218
+ }
195
219
  //#endregion
196
220
  //#region src/testing.ts
197
221
  /**
@@ -334,6 +358,7 @@ function createMockAddonServerContext(addonId, options = {}) {
334
358
  } },
335
359
  getConfig: async (_targetSiteId) => config,
336
360
  getUser: async (userId) => userId === defaultUser.id ? defaultUser : null,
361
+ findUserByName: async (name) => name === defaultUser.name ? defaultUser : null,
337
362
  getUsers: async (userIds) => {
338
363
  const map = /* @__PURE__ */ new Map();
339
364
  for (const id of userIds) if (id === defaultUser.id) map.set(id, defaultUser);
@@ -465,4 +490,4 @@ function verifyAddonEntitlement(addonId, target) {
465
490
  return true;
466
491
  }
467
492
  //#endregion
468
- export { hasPermission as _, useAddonSDK as a, useAddonInfiniteQuery as c, useQueryClient as d, AbilityBuilder as f, createMongoAbility as g, createAddonAbility as h, getAddonSdkVersion as i, useAddonMutation as l, authorizeResourceOwnership as m, defineAddonManifest as n, verifyAddonEntitlement as o, ForbiddenError as p, defineAddonServer as r, createMockAddonServerContext as s, AddonPipelineAbortError as t, useAddonQuery as u, subject as v };
493
+ export { createMongoAbility as _, useAddonSDK as a, useAddonInfiniteQuery as c, useAddonSettings as d, useQueryClient as f, createAddonAbility as g, authorizeResourceOwnership as h, getAddonSdkVersion as i, useAddonMutation as l, ForbiddenError as m, defineAddonManifest as n, verifyAddonEntitlement as o, AbilityBuilder as p, defineAddonServer as r, createMockAddonServerContext as s, AddonPipelineAbortError as t, useAddonQuery as u, hasPermission as v, subject as y };
@@ -1,2 +1,2 @@
1
- import { MockAddonContextResult, MockAddonServerContextOptions, createMockAddonServerContext } from "./index2.mjs";
1
+ import { MockAddonContextResult, MockAddonServerContextOptions, createMockAddonServerContext } from "./index.mjs";
2
2
  export { MockAddonContextResult, MockAddonServerContextOptions, createMockAddonServerContext };
package/dist/ui.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { _ as AddonUser, d as AddonRequestUser } from "./contracts2.mjs";
2
2
  import React from "react";
3
+ import ui_default from "@jchat/ui";
3
4
  import { Can } from "@casl/react";
4
5
  export * from "@jchat/ui";
5
6
  //#region src/ui.d.ts
@@ -38,5 +39,10 @@ export interface AddonCanProps {
38
39
  * @param children Content rendered when access is granted
39
40
  */
40
41
  export declare function AddonCan({ actor, ownerId, ownPermission, anyPermission, permission, fallback, children }: AddonCanProps): React.ReactElement | null;
42
+ /** Standard loading spinner for addon settings views. */
43
+ export declare function AddonSettingsLoading({ message, className }: {
44
+ message?: string;
45
+ className?: string;
46
+ }): React.ReactElement;
41
47
  //#endregion
42
- export { Can };
48
+ export { Can, ui_default as default };
package/dist/ui.mjs CHANGED
@@ -1,4 +1,6 @@
1
- import { _ as hasPermission } from "./src.mjs";
1
+ import { v as hasPermission } from "./src.mjs";
2
+ import React from "react";
3
+ import ui_default from "@jchat/ui";
2
4
  import { Can } from "@casl/react";
3
5
  export * from "@jchat/ui";
4
6
  //#region src/ui.ts
@@ -29,5 +31,9 @@ function AddonCan({ actor, ownerId, ownPermission, anyPermission, permission, fa
29
31
  }
30
32
  return children;
31
33
  }
34
+ /** Standard loading spinner for addon settings views. */
35
+ function AddonSettingsLoading({ message = "Loading configuration...", className }) {
36
+ return React.createElement("div", { className: "flex items-center justify-center p-8 text-sm text-muted-foreground" + (className ? ` ${className}` : "") }, React.createElement("span", { className: "me-2 inline-block size-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }), message);
37
+ }
32
38
  //#endregion
33
- export { AddonCan, Can };
39
+ export { AddonCan, AddonSettingsLoading, Can, ui_default as default };
package/dist/vite.mjs CHANGED
@@ -60,8 +60,7 @@ function jchatAddon(options) {
60
60
  "@tanstack/react-query",
61
61
  "@jchat/addon-sdk",
62
62
  "@jchat/addon-sdk/state",
63
- "@jchat/addon-sdk/ui",
64
- "@jchat/addon-sdk/icon"
63
+ "@jchat/addon-sdk/ui"
65
64
  ],
66
65
  output: { format: "esm" }
67
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jchat/addon-sdk",
3
- "version": "1.0.0-alpha.30",
3
+ "version": "1.0.0-alpha.31",
4
4
  "private": false,
5
5
  "description": "JChat Addon SDK for building JChat addons.",
6
6
  "keywords": [
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "files": [
21
21
  "dist",
22
+ "src/tailwind.css",
22
23
  "tsconfig.addon.json",
23
24
  "skills",
24
25
  "README.md",
@@ -70,25 +71,16 @@
70
71
  "default": "./src/i18n-validator.ts"
71
72
  },
72
73
  "./ui": {
74
+ "style": "./src/tailwind.css",
73
75
  "types": "./src/ui.ts",
74
76
  "import": "./src/ui.ts",
75
77
  "default": "./src/ui.ts"
76
78
  },
77
- "./icon": {
78
- "types": "./src/icon.ts",
79
- "import": "./src/icon.ts",
80
- "default": "./src/icon.ts"
81
- },
82
79
  "./state": {
83
80
  "types": "./src/state.ts",
84
81
  "import": "./src/state.ts",
85
82
  "default": "./src/state.ts"
86
83
  },
87
- "./ui/tailwind.css": {
88
- "style": "./src/tailwind.css",
89
- "import": "./src/tailwind.css",
90
- "default": "./src/tailwind.css"
91
- },
92
84
  "./tsconfig.json": "./tsconfig.addon.json"
93
85
  },
94
86
  "publishConfig": {
@@ -128,22 +120,14 @@
128
120
  "import": "./dist/i18n-validator.mjs"
129
121
  },
130
122
  "./ui": {
123
+ "style": "./src/tailwind.css",
131
124
  "types": "./dist/ui.d.mts",
132
125
  "import": "./dist/ui.mjs"
133
126
  },
134
- "./icon": {
135
- "types": "./dist/icon.d.mts",
136
- "import": "./dist/icon.mjs"
137
- },
138
127
  "./state": {
139
128
  "types": "./dist/state.d.mts",
140
129
  "import": "./dist/state.mjs"
141
130
  },
142
- "./ui/tailwind.css": {
143
- "style": "./src/tailwind.css",
144
- "import": "./src/tailwind.css",
145
- "default": "./src/tailwind.css"
146
- },
147
131
  "./tsconfig.json": "./tsconfig.addon.json"
148
132
  },
149
133
  "access": "public"
@@ -153,7 +137,7 @@
153
137
  "lint": "oxlint .",
154
138
  "format": "oxfmt . --write",
155
139
  "test": "bun test",
156
- "typecheck": "tsc --noEmit"
140
+ "typecheck": "bun check"
157
141
  },
158
142
  "dependencies": {
159
143
  "@casl/ability": "catalog:",
@@ -161,7 +145,6 @@
161
145
  "lucide-react": "catalog:"
162
146
  },
163
147
  "devDependencies": {
164
- "@jchat/icon": "workspace:*",
165
148
  "@jchat/ui": "workspace:*",
166
149
  "@tailwindcss/vite": "catalog:",
167
150
  "@tanstack/react-query": "catalog:",
@@ -169,7 +152,7 @@
169
152
  "@types/react": "catalog:",
170
153
  "elysia": "catalog:",
171
154
  "jotai": "catalog:",
172
- "kysely": "^catalog:",
155
+ "kysely": "catalog:",
173
156
  "tsdown": "catalog:",
174
157
  "vite": "catalog:"
175
158
  },
@@ -178,7 +161,7 @@
178
161
  "@tanstack/react-query": "catalog:",
179
162
  "elysia": "catalog:",
180
163
  "jotai": "catalog:",
181
- "kysely": "^catalog:",
164
+ "kysely": "catalog:",
182
165
  "react": "catalog:",
183
166
  "vite": "catalog:"
184
167
  }
@@ -12,11 +12,11 @@ Use this skill when developing, updating, or debugging JChat addons using `@jcha
12
12
  ## 1. Architectural Guardrails (Non-Negotiable)
13
13
 
14
14
  1. **Import Boundaries**:
15
- - Addons MUST ONLY import `@jchat/addon-sdk` and `@jchat/addon-sdk/icon`.
16
- - NEVER import private internal monorepo packages (`@jchat/icon`, `@jchat/ui`, `@jchat/db`, `@jchat/shared`, etc.).
15
+ - Addons MUST ONLY import `@jchat/addon-sdk`, `@jchat/addon-sdk/ui` (components, icons & toast), `@jchat/addon-sdk/state` (atomic state), and `@jchat/addon-sdk/server`.
16
+ - NEVER import private internal monorepo packages (`@jchat/ui`, `@jchat/db`, `@jchat/shared`, etc.).
17
17
  - Host externals (`react`, `react-dom`, `@tanstack/react-query`) are provided at runtime by the JChat host.
18
18
  2. **Icons**:
19
- - Use direct imports: `import Icons from "@jchat/addon-sdk/icon"`.
19
+ - Use direct imports: `import { Icons } from "@jchat/addon-sdk/ui"`.
20
20
  - Never call `useIcons()` or install `lucide-react` / `react-icons` directly in the addon.
21
21
  3. **Database Isolation**:
22
22
  - All addon tables MUST reside in the isolated `addons` PostgreSQL schema (e.g. `addons.GlimpseStories`).
@@ -98,7 +98,7 @@ import {
98
98
  useAddonMutation,
99
99
  useAddonTranslation
100
100
  } from "@jchat/addon-sdk"
101
- import Icons from "@jchat/addon-sdk/icon"
101
+ import { Icons } from "@jchat/addon-sdk/ui"
102
102
 
103
103
  export default function PollwiseAddon({ mountPoint, roomId }: AddonProps) {
104
104
  const sdk = useAddonSDK()
@@ -154,7 +154,7 @@ export default function PollwiseAddon({ mountPoint, roomId }: AddonProps) {
154
154
  Icons are rendered directly:
155
155
 
156
156
  ```tsx
157
- import Icons, { resolveIcon } from "@jchat/addon-sdk/icon"
157
+ import { Icons, resolveIcon } from "@jchat/addon-sdk/ui"
158
158
 
159
159
  // Direct JSX:
160
160
  <Icons.Sparkles className="size-4 text-primary" />
@@ -0,0 +1 @@
1
+ @import "@jchat/ui/tailwind.css";
package/dist/icon.d.mts DELETED
@@ -1,4 +0,0 @@
1
- import { i as IconPack, n as IconComponent, r as IconName, t as ICON_NAMES } from "./types.mjs";
2
- import { a as getIconPack, c as lucidePack, i as fa6Pack, l as phosphorPack, n as Icons, o as heroPack, r as Youtube, s as isIconName, t as IconPackName, u as resolveIcon } from "./index.mjs";
3
- export * from "lucide-react";
4
- export { ICON_NAMES, type IconComponent, type IconName, type IconPack, IconPackName, Icons, Icons as default, Youtube, fa6Pack, getIconPack, heroPack, isIconName, lucidePack, phosphorPack, resolveIcon };
package/dist/icon.mjs DELETED
@@ -1,4 +0,0 @@
1
- import { i as IconPack, n as IconComponent, r as IconName, t as ICON_NAMES } from "./types.d.mts";
2
- import { a as getIconPack, c as lucidePack, i as fa6Pack, l as phosphorPack, n as Icons, o as heroPack, r as Youtube, s as isIconName, t as IconPackName, u as resolveIcon } from "./index.d.mts";
3
- export * from "lucide-react";
4
- export { ICON_NAMES, IconComponent, IconName, IconPack, IconPackName, Icons, Icons as default, Youtube, fa6Pack, getIconPack, heroPack, isIconName, lucidePack, phosphorPack, resolveIcon };