@softr/sdk 0.0.54 → 0.0.56-alpha.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.
Files changed (38) hide show
  1. package/dist/action.d.ts +31 -1
  2. package/dist/action.js +26 -1
  3. package/dist/auth/isomorphic.d.ts +1 -1
  4. package/dist/auth/isomorphic.js +1 -2
  5. package/dist/client.d.ts +2 -1
  6. package/dist/client.js +2 -1
  7. package/dist/comments/comments.d.ts +168 -0
  8. package/dist/comments/comments.js +413 -0
  9. package/dist/comments/use-comment-composer.d.ts +46 -0
  10. package/dist/comments/use-comment-composer.js +134 -0
  11. package/dist/core/file-upload.d.ts +7 -2
  12. package/dist/core/file-upload.js +6 -1
  13. package/dist/core/use-file-upload.d.ts +2 -2
  14. package/dist/default-error-overlay.d.ts +2 -2
  15. package/dist/fetch.js +2 -2
  16. package/dist/index.d.ts +3 -3
  17. package/dist/index.js +2 -3
  18. package/dist/mcp.d.ts +2 -2
  19. package/dist/package.js +1 -1
  20. package/dist/server.d.ts +2 -1
  21. package/dist/server.js +2 -1
  22. package/package.json +3 -1
  23. package/skills/softr-sdk/SKILL.md +7 -7
  24. package/skills/softr-sdk/auth/SKILL.md +1 -1
  25. package/skills/softr-sdk/charts-and-metrics/SKILL.md +1 -1
  26. package/skills/softr-sdk/comments/SKILL.md +182 -0
  27. package/skills/softr-sdk/current-user/SKILL.md +1 -1
  28. package/skills/softr-sdk/file-uploads/SKILL.md +5 -4
  29. package/skills/softr-sdk/integrations/SKILL.md +1 -1
  30. package/skills/softr-sdk/mcp/SKILL.md +1 -1
  31. package/skills/softr-sdk/record-mutations/SKILL.md +1 -1
  32. package/skills/softr-sdk/record-queries/SKILL.md +2 -2
  33. package/skills/softr-sdk/region-visibility/SKILL.md +1 -1
  34. package/skills/softr-sdk/routes-and-visibility/SKILL.md +1 -1
  35. package/skills/softr-sdk/workflows/SKILL.md +1 -1
  36. package/dist/pwa.d.ts +0 -54
  37. package/dist/pwa.js +0 -152
  38. package/skills/softr-sdk/pwa/SKILL.md +0 -77
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.54
12
+ library_version: 0.0.56-alpha.0
13
13
  ---
14
14
 
15
15
  **Boundary.** `softrMcpMiddleware` lives on `@softr/sdk` and is registered once, in `src/start.ts`. The actions you hand it are the same `defineQuery` / `defineMutation` values the app's own pages use — declared wherever they already live, not duplicated for MCP.
@@ -11,7 +11,7 @@ description: >-
11
11
  metadata:
12
12
  type: sub-skill
13
13
  library: softr-sdk
14
- library_version: 0.0.54
14
+ library_version: 0.0.56-alpha.0
15
15
  ---
16
16
 
17
17
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineMutation` and every type come from `@softr/sdk` and can be imported anywhere.
@@ -13,10 +13,10 @@ description: >-
13
13
  metadata:
14
14
  type: sub-skill
15
15
  library: softr-sdk
16
- library_version: 0.0.54
16
+ library_version: 0.0.56-alpha.0
17
17
  ---
18
18
 
19
- **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. The same holds for any helper that calls `ds`: declare it inside the handler. A function at module level that calls `ds` keeps the server-only import in the browser bundle, and every page stops loading until it moves. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
19
+ **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
20
20
 
21
21
  # Reading records
22
22
 
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.54
12
+ library_version: 0.0.56-alpha.0
13
13
  ---
14
14
 
15
15
  **Boundary.** `Audience` and `defineVisibility` come from `@softr/sdk` and work anywhere.
@@ -13,7 +13,7 @@ description: >-
13
13
  metadata:
14
14
  type: sub-skill
15
15
  library: softr-sdk
16
- library_version: 0.0.54
16
+ library_version: 0.0.56-alpha.0
17
17
  ---
18
18
 
19
19
  **Boundary.** `defineVisibility`, the access functions and the error predicates come from `@softr/sdk` and work anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.54
12
+ library_version: 0.0.56-alpha.0
13
13
  ---
14
14
 
15
15
  **Boundary.** `workflow` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineWorkflow` and every type come from `@softr/sdk` and can be imported anywhere.
package/dist/pwa.d.ts DELETED
@@ -1,54 +0,0 @@
1
- import * as react0 from "react";
2
- import "@tanstack/react-start";
3
-
4
- //#region src/pwa.d.ts
5
-
6
- /**
7
- * The links that make the app installable: its manifest and its home screen
8
- * icon. Render it once, in `<head>` in the root route's `RootDocument`.
9
- *
10
- * @example
11
- * function RootDocument({ children }: { children: React.ReactNode }) {
12
- * return (
13
- * <html lang="en">
14
- * <head>
15
- * <HeadContent />
16
- * <SoftrPwaHead />
17
- * </head>
18
- * <body>
19
- * {children}
20
- * <Scripts />
21
- * </body>
22
- * </html>
23
- * )
24
- * }
25
- */
26
- declare function SoftrPwaHead(): react0.FunctionComponentElement<react0.FragmentProps>;
27
- type PwaPlatform = "ios" | "android" | "desktop";
28
- type PwaInstall = {
29
- available: false;
30
- } | {
31
- available: true;
32
- /** Which steps install the app on this device. */
33
- platform: PwaPlatform;
34
- /** The name the home screen will show. */
35
- name: string;
36
- /** The icon the home screen will show. */
37
- iconUrl: string;
38
- };
39
- /**
40
- * Whether to offer installing the app, and on which platform. Render an
41
- * install button only while this says `available`: it is unavailable while
42
- * loading, when the builder has not turned the PWA on, when Softr has switched
43
- * it off, and when the app already runs installed.
44
- *
45
- * @example
46
- * function InstallButton() {
47
- * const install = usePwaInstall()
48
- * if (!install.available) return null
49
- * return <button onClick={() => openSteps(install.platform)}>Install {install.name}</button>
50
- * }
51
- */
52
- declare function usePwaInstall(): PwaInstall;
53
- //#endregion
54
- export { PwaInstall, PwaPlatform, SoftrPwaHead, usePwaInstall };
package/dist/pwa.js DELETED
@@ -1,152 +0,0 @@
1
- import { logger } from "./logger.js";
2
- import { fetch } from "./fetch.js";
3
- import { sessionConfig } from "./auth/config.js";
4
- import { platformApiUrl } from "./auth/platform.js";
5
- import { Fragment, createElement, useEffect, useState } from "react";
6
- import { createMiddleware } from "@tanstack/react-start";
7
- import { z } from "zod";
8
-
9
- //#region src/pwa.ts
10
- const MANIFEST_PATH = "/manifest.webmanifest";
11
- const ICON_PATH = "/apple-touch-icon.png";
12
- const INSTALL_PATH = "/_softr/pwa.json";
13
- const TTL_MS = 6e4;
14
- const CACHE_CONTROL = "public, max-age=60";
15
- const pwaSchema = z.object({
16
- manifest: z.record(z.string(), z.unknown()),
17
- install: z.object({
18
- name: z.string(),
19
- iconUrl: z.string()
20
- })
21
- });
22
- let cached;
23
- /**
24
- * The app's PWA, or `null` when it is not installable right now. Never
25
- * rejects: a failure reads as not installable and is not remembered, so the
26
- * next request tries again.
27
- */
28
- function readPwa() {
29
- const now = Date.now();
30
- if (cached !== void 0 && cached.expires > now) return cached.pwa;
31
- const entry = {
32
- expires: now + TTL_MS,
33
- pwa: fetchPwa().catch((error) => {
34
- logger.warn("Could not read the PWA settings:", error);
35
- if (cached === entry) cached = void 0;
36
- return null;
37
- })
38
- };
39
- cached = entry;
40
- return entry.pwa;
41
- }
42
- async function fetchPwa() {
43
- const { applicationId } = sessionConfig();
44
- const response = await fetch(`${await platformApiUrl()}/v1/vibe/applications/${applicationId}/pwa`, { headers: { accept: "application/json" } });
45
- if (response.status === 404) return null;
46
- if (!response.ok) throw new Error(`The platform answered ${response.status}`);
47
- return pwaSchema.parse(await response.json());
48
- }
49
- /**
50
- * Serves the app's web app manifest, its home screen icon, and what an install
51
- * button needs to know, from the app's own origin. Every other request passes
52
- * through untouched.
53
- *
54
- * Answers 404, never an error page, when the app is not installable: a browser
55
- * silently drops a manifest it cannot parse, so a 500 there would be invisible.
56
- */
57
- function pwaMiddleware() {
58
- return createMiddleware({ type: "request" }).server(async ({ next, pathname }) => {
59
- if (pathname !== MANIFEST_PATH && pathname !== ICON_PATH && pathname !== INSTALL_PATH) return next();
60
- const pwa = await readPwa();
61
- if (pwa === null) return new Response(null, { status: 404 });
62
- if (pathname === MANIFEST_PATH) return new Response(JSON.stringify(pwa.manifest), { headers: {
63
- "content-type": "application/manifest+json",
64
- "cache-control": CACHE_CONTROL
65
- } });
66
- if (pathname === INSTALL_PATH) return Response.json(pwa.install, { headers: { "cache-control": CACHE_CONTROL } });
67
- try {
68
- const iconResponse = await fetch(pwa.install.iconUrl);
69
- if (!iconResponse.ok) return new Response(null, { status: 404 });
70
- return new Response(iconResponse.body, { headers: {
71
- "content-type": "image/png",
72
- "cache-control": CACHE_CONTROL
73
- } });
74
- } catch (error) {
75
- logger.warn("Could not fetch the PWA icon:", error);
76
- return new Response(null, { status: 404 });
77
- }
78
- });
79
- }
80
- /**
81
- * The links that make the app installable: its manifest and its home screen
82
- * icon. Render it once, in `<head>` in the root route's `RootDocument`.
83
- *
84
- * @example
85
- * function RootDocument({ children }: { children: React.ReactNode }) {
86
- * return (
87
- * <html lang="en">
88
- * <head>
89
- * <HeadContent />
90
- * <SoftrPwaHead />
91
- * </head>
92
- * <body>
93
- * {children}
94
- * <Scripts />
95
- * </body>
96
- * </html>
97
- * )
98
- * }
99
- */
100
- function SoftrPwaHead() {
101
- return createElement(Fragment, null, createElement("link", {
102
- rel: "manifest",
103
- href: MANIFEST_PATH
104
- }), createElement("link", {
105
- rel: "apple-touch-icon",
106
- href: ICON_PATH
107
- }));
108
- }
109
- const installSchema = pwaSchema.shape.install;
110
- /**
111
- * Whether to offer installing the app, and on which platform. Render an
112
- * install button only while this says `available`: it is unavailable while
113
- * loading, when the builder has not turned the PWA on, when Softr has switched
114
- * it off, and when the app already runs installed.
115
- *
116
- * @example
117
- * function InstallButton() {
118
- * const install = usePwaInstall()
119
- * if (!install.available) return null
120
- * return <button onClick={() => openSteps(install.platform)}>Install {install.name}</button>
121
- * }
122
- */
123
- function usePwaInstall() {
124
- const [install, setInstall] = useState({ available: false });
125
- useEffect(() => {
126
- if (window.matchMedia("(display-mode: standalone)").matches || "standalone" in navigator && navigator.standalone === true) return;
127
- let cancelled = false;
128
- fetch(INSTALL_PATH, { headers: { accept: "application/json" } }).then(async (response) => {
129
- if (!response.ok) return;
130
- const parsed = installSchema.safeParse(await response.json());
131
- if (!parsed.success || cancelled) return;
132
- setInstall({
133
- available: true,
134
- platform: detectPlatform(),
135
- ...parsed.data
136
- });
137
- }).catch(() => {});
138
- return () => {
139
- cancelled = true;
140
- };
141
- }, []);
142
- return install;
143
- }
144
- function detectPlatform() {
145
- const userAgent = navigator.userAgent;
146
- if (/iPhone|iPad|iPod/.test(userAgent) || /Macintosh/.test(userAgent) && navigator.maxTouchPoints > 1) return "ios";
147
- if (/Android/.test(userAgent)) return "android";
148
- return "desktop";
149
- }
150
-
151
- //#endregion
152
- export { SoftrPwaHead, pwaMiddleware, usePwaInstall };
@@ -1,77 +0,0 @@
1
- ---
2
- name: pwa
3
- description: >-
4
- Let visitors install the app on their home screen: SoftrPwaHead for the
5
- manifest and icon links, usePwaInstall to decide whether to show an install
6
- button and which platform's steps to show, the PwaInstall and PwaPlatform
7
- types, and how to check that the app is installable. The manifest and icon
8
- are already served; never write them.
9
- metadata:
10
- type: sub-skill
11
- library: softr-sdk
12
- library_version: 0.0.54
13
- ---
14
-
15
- # Installing the app
16
-
17
- The builder turns installing on in Studio, under Settings → Mobile app, and sets the name, colour and icon there. The app already answers with its manifest and icon once they do. What the app adds is two things: the links that point the browser at them, and a button that tells visitors how to install.
18
-
19
- > **CRITICAL**: Never write a web app manifest, icon files, a service worker, or `manifest` / `apple-touch-icon` links of your own, in `public/` or in `head()`. The app already serves them from Studio's settings, and a file of your own shadows those settings.
20
- > **CRITICAL**: Render an install button only while `usePwaInstall()` returns `available: true`. Never show it unconditionally, never cache the answer, never replace the check with your own. Softr can switch installing off for an app, and this check is the only way that reaches the button.
21
-
22
- ## Setup
23
-
24
- ```ts
25
- import { SoftrPwaHead, usePwaInstall } from '@softr/sdk'
26
- import type { PwaInstall, PwaPlatform } from '@softr/sdk'
27
- ```
28
-
29
- ```ts
30
- type PwaPlatform = 'ios' | 'android' | 'desktop'
31
-
32
- type PwaInstall =
33
- | { available: false }
34
- | {
35
- available: true
36
- platform: PwaPlatform // which steps install the app on this device
37
- name: string // what the home screen will show
38
- iconUrl: string // the icon the home screen will show
39
- }
40
- ```
41
-
42
- ## Is the app installable?
43
-
44
- The builder switches installing on in Studio, and `usePwaInstall()` reads that switch at runtime. To check it before writing any code, ask the running app for `/_softr/pwa.json`: `200` means installable, `404` means installing is off or there is no icon yet. Do not build an install button against a `404`: installing has to be turned on first. A change in Studio can take up to two minutes to reach the app.
45
-
46
- ## Core Patterns
47
-
48
- ### The links: `<SoftrPwaHead />`
49
-
50
- Render it once, in `<head>` next to `<HeadContent />`, in `RootDocument` in `src/routes/__root.tsx`.
51
-
52
- ```tsx
53
- function RootDocument({ children }: { children: React.ReactNode }) {
54
- return (
55
- <html lang="en">
56
- <head>
57
- <HeadContent />
58
- <SoftrPwaHead />
59
- </head>
60
- <body>
61
- {children}
62
- <Scripts />
63
- </body>
64
- </html>
65
- )
66
- }
67
- ```
68
-
69
- ### Whether to show a button: `usePwaInstall()`
70
-
71
- It fetches after mount, so the first render, the server render included, always says `available: false`. It stays unavailable when the app is not installable, when the request fails, and when the app already runs installed from the home screen. Inside the Studio preview it says available, so the builder can see the button; installing itself only works on the published app.
72
-
73
- There is no `install()` to call. No browser opens its install dialog for this app on request, so the button opens steps for `platform` instead: Share, then Add to Home Screen on iOS; the browser menu's Install app on Android and desktop. `name` and `iconUrl` tell the visitor what they are adding.
74
-
75
- ## References
76
-
77
- - [SKILL.md](../SKILL.md): the entrypoints and which one each export lives on