@pylonsync/create-pylon 0.9.1 → 0.10.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/package.json +1 -1
- package/templates/_root/AGENTS.md +11 -0
- package/templates/agency/AGENTS.md +11 -0
- package/templates/ai-chat/AGENTS.md +11 -0
- package/templates/ai-studio/AGENTS.md +11 -0
- package/templates/backend/mobile/apps/api/README.md +20 -1
- package/templates/backend/mobile/apps/api/app/(site)/layout.tsx +103 -0
- package/templates/backend/mobile/apps/api/app/(site)/not-found.tsx +23 -0
- package/templates/backend/mobile/apps/api/app/(site)/page.tsx +221 -0
- package/templates/backend/mobile/apps/api/app/(site)/privacy/page.tsx +131 -0
- package/templates/backend/mobile/apps/api/app/(site)/support/page.tsx +78 -0
- package/templates/backend/mobile/apps/api/app/(site)/terms/page.tsx +144 -0
- package/templates/backend/mobile/apps/api/app/error.tsx +27 -0
- package/templates/backend/mobile/apps/api/app/globals.css +87 -0
- package/templates/backend/mobile/apps/api/app/layout.tsx +27 -0
- package/templates/backend/mobile/apps/api/app/robots.ts +13 -0
- package/templates/backend/mobile/apps/api/app/sitemap.ts +16 -0
- package/templates/backend/mobile/apps/api/app.ts +6 -2
- package/templates/backend/mobile/apps/api/components/legal.tsx +64 -0
- package/templates/backend/mobile/apps/api/lib/site.ts +94 -0
- package/templates/backend/mobile/apps/api/package.json +8 -1
- package/templates/backend/mobile/apps/api/tsconfig.json +6 -2
- package/templates/barebones/AGENTS.md +11 -0
- package/templates/chat/AGENTS.md +11 -0
- package/templates/consumer/AGENTS.md +11 -0
- package/templates/creator/AGENTS.md +11 -0
- package/templates/crm/AGENTS.md +11 -0
- package/templates/directory/AGENTS.md +11 -0
- package/templates/expo/mobile/apps/expo/.env.example +13 -4
- package/templates/expo/mobile/apps/expo/README.md +9 -0
- package/templates/expo/mobile/apps/expo/STORE.md +9 -5
- package/templates/expo/mobile/apps/expo/app/(tabs)/settings.tsx +9 -6
- package/templates/expo/mobile/apps/expo/app/paywall.tsx +9 -13
- package/templates/expo/mobile/apps/expo/src/links.ts +29 -0
- package/templates/helpdesk/AGENTS.md +11 -0
- package/templates/inventory/AGENTS.md +11 -0
- package/templates/invoices/AGENTS.md +11 -0
- package/templates/local-service/AGENTS.md +11 -0
- package/templates/marketplace/AGENTS.md +11 -0
- package/templates/projects/AGENTS.md +11 -0
- package/templates/restaurant/AGENTS.md +11 -0
- package/templates/saas/AGENTS.md +11 -0
- package/templates/saas/app/dashboard/layout.tsx +9 -2
- package/templates/saas/app/dashboard/page.tsx +37 -14
- package/templates/saas/app/dashboard/settings/page.tsx +11 -4
- package/templates/shop/AGENTS.md +11 -0
- package/templates/todo/AGENTS.md +11 -0
- package/templates/waitlist/AGENTS.md +11 -0
package/templates/todo/AGENTS.md
CHANGED
|
@@ -48,6 +48,17 @@ this pass before the user has to ask.
|
|
|
48
48
|
- **`error.tsx` / `not-found.tsx` boundaries are HYDRATED (interactive).** `app/.../error.tsx` catches a throw below it (HTTP 500) and receives `{ error: { message, digest }, reset }` (`import type { ErrorBoundaryProps }`); `reset()` re-attempts the route; the stack NEVER reaches the client (dev overlay + logs only). `app/.../not-found.tsx` renders at 404 (also for `response.notFound()`) and gets the page props (`NotFoundProps`), no `reset`. Both run useState/onClick/hooks.
|
|
49
49
|
- **Client navigation hooks live in @pylonsync/react.** `useRouter()` → `{ push, replace, back, forward, refresh, prefetch }`; `useSearchParams()` → reactive `URLSearchParams`; `usePathname()` → reactive pathname. The hooks are CLIENT-reactive; during SSR they return defaults (empty params / "/"); for server-side URL values read the `pathname` / `searchParams` page props (`pathname` is the PATH only — the query is already parsed into `searchParams`, so never try to read a query parameter back out of it; the older `url` prop is the same value and is deprecated).
|
|
50
50
|
- **Dynamic + catch-all routes follow Next conventions.** `app/blog/[slug]/page.tsx` → `params.slug`. `app/docs/[...path]/page.tsx` is a catch-all (matches `/docs/a/b/c`; `params.path === "a/b/c"`; `.split("/")` for segments). `app/shop/[[...filters]]/page.tsx` is an optional catch-all (also matches the bare `/shop`, with `params.filters === ""`). A catch-all must be the last segment; static beats dynamic beats catch-all on overlap.
|
|
51
|
+
- **Never wrap `serverData` calls in `Promise.all`.** Each method returns a thenable the handle CACHES by key — on the client it is already fulfilled, so `use()` returns synchronously. `Promise.all` builds a new, pending, uncached promise on every render, so `use()` suspends, re-renders, builds another, and the page never returns; React reports it as an async Client Component (minified error #482) and the error boundary shows a broken page. To read several things in parallel, START every call before the first `use()`, then `use()` each handle — the reads overlap and the replayed render finds each one cached:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
const orgPromise = serverData.get<Org>("Org", auth.tenant_id);
|
|
55
|
+
const projectsPromise = serverData.list<Project>("Project");
|
|
56
|
+
const org = use(orgPromise);
|
|
57
|
+
const projects = use(projectsPromise);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Reading them one at a time (`use(serverData.a()); use(serverData.b());`) is correct but serial: each read waits for the one above it.
|
|
61
|
+
|
|
51
62
|
- **`serverData` (SSR) is READ-ONLY.** No write methods; the runtime rejects write frames (`SSR_WRITE_FORBIDDEN`). Mutations belong in actions/functions, never in a page render.
|
|
52
63
|
- **`response.*` / `response.redirect()` / `response.notFound()` must fire in the synchronous shell render**, before any `await` / `<Suspense>`. The HTTP head commits when the shell is ready; status/headers/cookies set from a suspended subtree are lost, and `redirect`/`notFound` thrown below a Suspense boundary are swallowed.
|
|
53
64
|
- **`ctx.llm`, `ctx.rooms`, and `ctx.connections` are on mutation + action only, NOT query** (reactive purity). `action` has no direct `ctx.db`; use `ctx.runQuery` / `ctx.runMutation`.
|
|
@@ -48,6 +48,17 @@ this pass before the user has to ask.
|
|
|
48
48
|
- **`error.tsx` / `not-found.tsx` boundaries are HYDRATED (interactive).** `app/.../error.tsx` catches a throw below it (HTTP 500) and receives `{ error: { message, digest }, reset }` (`import type { ErrorBoundaryProps }`); `reset()` re-attempts the route; the stack NEVER reaches the client (dev overlay + logs only). `app/.../not-found.tsx` renders at 404 (also for `response.notFound()`) and gets the page props (`NotFoundProps`), no `reset`. Both run useState/onClick/hooks.
|
|
49
49
|
- **Client navigation hooks live in @pylonsync/react.** `useRouter()` → `{ push, replace, back, forward, refresh, prefetch }`; `useSearchParams()` → reactive `URLSearchParams`; `usePathname()` → reactive pathname. The hooks are CLIENT-reactive; during SSR they return defaults (empty params / "/"); for server-side URL values read the `pathname` / `searchParams` page props (`pathname` is the PATH only — the query is already parsed into `searchParams`, so never try to read a query parameter back out of it; the older `url` prop is the same value and is deprecated).
|
|
50
50
|
- **Dynamic + catch-all routes follow Next conventions.** `app/blog/[slug]/page.tsx` → `params.slug`. `app/docs/[...path]/page.tsx` is a catch-all (matches `/docs/a/b/c`; `params.path === "a/b/c"`; `.split("/")` for segments). `app/shop/[[...filters]]/page.tsx` is an optional catch-all (also matches the bare `/shop`, with `params.filters === ""`). A catch-all must be the last segment; static beats dynamic beats catch-all on overlap.
|
|
51
|
+
- **Never wrap `serverData` calls in `Promise.all`.** Each method returns a thenable the handle CACHES by key — on the client it is already fulfilled, so `use()` returns synchronously. `Promise.all` builds a new, pending, uncached promise on every render, so `use()` suspends, re-renders, builds another, and the page never returns; React reports it as an async Client Component (minified error #482) and the error boundary shows a broken page. To read several things in parallel, START every call before the first `use()`, then `use()` each handle — the reads overlap and the replayed render finds each one cached:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
const orgPromise = serverData.get<Org>("Org", auth.tenant_id);
|
|
55
|
+
const projectsPromise = serverData.list<Project>("Project");
|
|
56
|
+
const org = use(orgPromise);
|
|
57
|
+
const projects = use(projectsPromise);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Reading them one at a time (`use(serverData.a()); use(serverData.b());`) is correct but serial: each read waits for the one above it.
|
|
61
|
+
|
|
51
62
|
- **`serverData` (SSR) is READ-ONLY.** No write methods; the runtime rejects write frames (`SSR_WRITE_FORBIDDEN`). Mutations belong in actions/functions, never in a page render.
|
|
52
63
|
- **`response.*` / `response.redirect()` / `response.notFound()` must fire in the synchronous shell render**, before any `await` / `<Suspense>`. The HTTP head commits when the shell is ready; status/headers/cookies set from a suspended subtree are lost, and `redirect`/`notFound` thrown below a Suspense boundary are swallowed.
|
|
53
64
|
- **`ctx.llm`, `ctx.rooms`, and `ctx.connections` are on mutation + action only, NOT query** (reactive purity). `action` has no direct `ctx.db`; use `ctx.runQuery` / `ctx.runMutation`.
|