@tiniestcloud/create 0.0.0-stage → 0.1.6
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 +26 -2
- package/index.mjs +117 -0
- package/package.json +33 -4
- package/sdk.d.ts +290 -0
- package/skills/tiny-design/SKILL.md +333 -0
- package/skills/tiny-design/app.md +72 -0
- package/skills/tiny-design/dashboard.md +54 -0
- package/skills/tiny-design/form.md +48 -0
- package/skills/tiny-design/presentation.md +127 -0
- package/skills/tiny-design/website.md +53 -0
- package/templates/app/AGENTS.md +41 -0
- package/templates/app/CLAUDE.md +1 -0
- package/templates/app/README.md +10 -0
- package/templates/app/components.json +25 -0
- package/templates/app/gitignore +24 -0
- package/templates/app/index.html +27 -0
- package/templates/app/package.json +32 -0
- package/templates/app/src/App.tsx +39 -0
- package/templates/app/src/components/theme-toggle.tsx +57 -0
- package/templates/app/src/components/ui/button.tsx +66 -0
- package/templates/app/src/components/ui/tooltip.tsx +54 -0
- package/templates/app/src/index.css +130 -0
- package/templates/app/src/lib/theme.ts +39 -0
- package/templates/app/src/lib/tiny.tsx +59 -0
- package/templates/app/src/lib/utils.ts +1 -0
- package/templates/app/src/main.tsx +20 -0
- package/templates/app/src/pages/home.tsx +10 -0
- package/templates/app/tsconfig.app.json +29 -0
- package/templates/app/tsconfig.json +12 -0
- package/templates/app/tsconfig.node.json +24 -0
- package/templates/app/vite.config.ts +14 -0
- package/templates/site/AGENTS.md +23 -0
- package/templates/site/CLAUDE.md +1 -0
- package/templates/site/README.md +10 -0
- package/templates/site/astro.config.mjs +11 -0
- package/templates/site/gitignore +24 -0
- package/templates/site/package.json +22 -0
- package/templates/site/src/layouts/Layout.astro +30 -0
- package/templates/site/src/pages/about.astro +10 -0
- package/templates/site/src/pages/index.astro +10 -0
- package/templates/site/src/styles/global.css +1 -0
- package/templates/site/tsconfig.json +5 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React helpers over the Tiniest Cloud SDK. `tiny` itself is a global — its types are in
|
|
3
|
+
* src/tiny.d.ts — so anything not wrapped here is called directly: `await tiny.db.set(key, value)`.
|
|
4
|
+
*/
|
|
5
|
+
import { useEffect, useState } from "react"
|
|
6
|
+
|
|
7
|
+
/** The signed-in person: undefined while loading, null when signed out. */
|
|
8
|
+
export function useMe(): Tiny.User | null | undefined {
|
|
9
|
+
const [me, setMe] = useState<Tiny.User | null | undefined>(undefined)
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
let live = true
|
|
12
|
+
tiny.me().then(
|
|
13
|
+
(user) => live && setMe(user),
|
|
14
|
+
() => live && setMe(null)
|
|
15
|
+
)
|
|
16
|
+
return () => {
|
|
17
|
+
live = false
|
|
18
|
+
}
|
|
19
|
+
}, [])
|
|
20
|
+
return me
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Every entry under a prefix, kept live: re-renders within a second of any change, from any
|
|
25
|
+
* device. `entries` is undefined until the first load.
|
|
26
|
+
*
|
|
27
|
+
* const { entries } = useEntries<Customer>("customer:", { where: { status: "active" } })
|
|
28
|
+
* const { entries: latest } = useEntries<Order>("order:", { order: "-$created_at", limit: 20 })
|
|
29
|
+
*/
|
|
30
|
+
export function useEntries<T>(prefix: string, options?: Tiny.Filter & Tiny.Ordered & { limit?: number }) {
|
|
31
|
+
const [entries, setEntries] = useState<Tiny.Entry<T>[] | undefined>(undefined)
|
|
32
|
+
const [error, setError] = useState<Tiny.TinyError | null>(null)
|
|
33
|
+
const where = JSON.stringify(options?.where ?? null)
|
|
34
|
+
const order = options?.order
|
|
35
|
+
const limit = options?.limit
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
setError(null)
|
|
38
|
+
return tiny.db.watch<T>(prefix, setEntries, {
|
|
39
|
+
where: JSON.parse(where) ?? undefined,
|
|
40
|
+
order,
|
|
41
|
+
limit,
|
|
42
|
+
onError: setError,
|
|
43
|
+
})
|
|
44
|
+
}, [prefix, where, order, limit])
|
|
45
|
+
return { entries, error }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Shown when the page is opened anywhere but Tiniest Cloud, e.g. by `npm run dev`. */
|
|
49
|
+
export function NotOnTiniestCloud() {
|
|
50
|
+
return (
|
|
51
|
+
<main className="mx-auto flex min-h-svh max-w-md flex-col justify-center gap-2 p-6 text-sm">
|
|
52
|
+
<h1 className="text-base font-medium">This app runs on Tiniest Cloud</h1>
|
|
53
|
+
<p className="text-muted-foreground">
|
|
54
|
+
Sign-in, data and AI come from the platform, so they only work once the app is
|
|
55
|
+
deployed. Build it, deploy the dist folder, and open the app's link.
|
|
56
|
+
</p>
|
|
57
|
+
</main>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { cn } from "cn"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { StrictMode } from "react"
|
|
2
|
+
import { createRoot } from "react-dom/client"
|
|
3
|
+
|
|
4
|
+
import "./index.css"
|
|
5
|
+
import App from "./App.tsx"
|
|
6
|
+
import { NotOnTiniestCloud } from "@/lib/tiny"
|
|
7
|
+
import { startTheme } from "@/lib/theme"
|
|
8
|
+
|
|
9
|
+
// Light, dark or the device's setting, as the person chose (src/lib/theme.ts); the colours
|
|
10
|
+
// themselves live in index.css.
|
|
11
|
+
startTheme()
|
|
12
|
+
|
|
13
|
+
// `tiny` exists only where Tiniest Cloud serves the app. Anywhere else — `npm run dev` included —
|
|
14
|
+
// say so, rather than let every screen fail on its first call.
|
|
15
|
+
const onPlatform = typeof window.tiny !== "undefined"
|
|
16
|
+
if (onPlatform && "serviceWorker" in navigator) navigator.serviceWorker.register("/sw.js")
|
|
17
|
+
|
|
18
|
+
createRoot(document.getElementById("root")!).render(
|
|
19
|
+
<StrictMode>{onPlatform ? <App /> : <NotOnTiniestCloud />}</StrictMode>
|
|
20
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first screen. Every screen is a file in src/pages; App.tsx frames them and, once there is
|
|
3
|
+
* more than one, routes to each (React Router). Lay this one out for what it holds: a sidebar for
|
|
4
|
+
* several areas, a grid of cards for things people browse, a table for records, a list with its
|
|
5
|
+
* detail beside it; a narrow centred column only for one focused task. Pieces it shares with
|
|
6
|
+
* other screens go in src/components, its own hooks in src/hooks.
|
|
7
|
+
*/
|
|
8
|
+
export default function Home() {
|
|
9
|
+
return <div />
|
|
10
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "es2023",
|
|
5
|
+
"lib": ["ES2023", "DOM"],
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"types": ["vite/client"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"jsx": "react-jsx",
|
|
17
|
+
|
|
18
|
+
/* Linting */
|
|
19
|
+
"strict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"erasableSyntaxOnly": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true,
|
|
24
|
+
"paths": {
|
|
25
|
+
"@/*": ["./src/*"]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"include": ["src"]
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
+
"target": "es2023",
|
|
5
|
+
"lib": ["ES2023"],
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"erasableSyntaxOnly": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["vite.config.ts"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import path from "path"
|
|
2
|
+
import tailwindcss from "@tailwindcss/vite"
|
|
3
|
+
import react from "@vitejs/plugin-react"
|
|
4
|
+
import { defineConfig } from "vite"
|
|
5
|
+
|
|
6
|
+
// https://vite.dev/config/
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [react(), tailwindcss()],
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
"@": path.resolve(import.meta.dirname, "./src"),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# This website runs on Tiniest Cloud
|
|
2
|
+
|
|
3
|
+
Astro and Tailwind CSS, built to static pages and deployed to Tiniest Cloud.
|
|
4
|
+
|
|
5
|
+
- Every file in src/pages is a page: src/pages/pricing.astro is served at /pricing/. Link to pages
|
|
6
|
+
with a trailing slash. Keep Astro's static output; there is no server to render on request.
|
|
7
|
+
- Where files go: pages in `src/pages/`, the frame they share in `src/layouts/`, pieces several
|
|
8
|
+
pages use in `src/components/`, styles in `src/styles/`, images and icons in `public/`. A file
|
|
9
|
+
past about 300 lines is doing too much: move its parts into components.
|
|
10
|
+
- `npm run build` writes the site to `dist`; deploy this folder with `dist` built inside (no
|
|
11
|
+
node_modules, no .env files): `dist` is served, and the rest is kept as the source. When
|
|
12
|
+
starting the dev server, use `astro dev --background` (`astro dev stop` to end it).
|
|
13
|
+
- A form that keeps what visitors send (sign-ups, contact requests) uses Tiniest Cloud's storage:
|
|
14
|
+
add `<script is:inline src="/sdk.js"></script>` to the layout's head, and see the Tiniest
|
|
15
|
+
Cloud guide on visitors with no account. Types for it are at /sdk.d.ts on the platform.
|
|
16
|
+
- Logic that must run on the server (checking or pricing what a form sends) is a backend function:
|
|
17
|
+
`public/_functions/<name>.js`, called from the page with `tiny.call("<name>", input)`. See the
|
|
18
|
+
Tiniest Cloud guide, "Server code".
|
|
19
|
+
- Design: before the first page, read the tiny-design skill — `.agents/skills/tiny-design/`
|
|
20
|
+
(the same files are in `.claude/skills/` for Claude Code): SKILL.md, then website.md. Where
|
|
21
|
+
that folder is missing, `tiny_guide` with topic `website` returns the same. If the person has
|
|
22
|
+
a brand or design standards of their own, those come first.
|
|
23
|
+
- Astro's docs: https://docs.astro.build
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Site
|
|
2
|
+
|
|
3
|
+
Built with Astro and Tailwind CSS, and hosted on Tiniest Cloud.
|
|
4
|
+
|
|
5
|
+
npm install
|
|
6
|
+
npm run dev # work on it locally
|
|
7
|
+
npm run build # the site is in dist/
|
|
8
|
+
|
|
9
|
+
Deploy this folder, with `dist` built inside, to Tiniest Cloud: `dist` is served, and the rest is
|
|
10
|
+
kept as the project's source.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# build output
|
|
2
|
+
dist/
|
|
3
|
+
# generated types
|
|
4
|
+
.astro/
|
|
5
|
+
|
|
6
|
+
# dependencies
|
|
7
|
+
node_modules/
|
|
8
|
+
|
|
9
|
+
# logs
|
|
10
|
+
npm-debug.log*
|
|
11
|
+
yarn-debug.log*
|
|
12
|
+
yarn-error.log*
|
|
13
|
+
pnpm-debug.log*
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# environment variables
|
|
17
|
+
.env
|
|
18
|
+
.env.production
|
|
19
|
+
|
|
20
|
+
# macOS-specific files
|
|
21
|
+
.DS_Store
|
|
22
|
+
|
|
23
|
+
# jetbrains setting folder
|
|
24
|
+
.idea/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "site",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22.12.0"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "astro dev",
|
|
11
|
+
"build": "astro build",
|
|
12
|
+
"astro": "astro"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
16
|
+
"astro": "^7.3.5",
|
|
17
|
+
"tailwindcss": "^4.3.3"
|
|
18
|
+
},
|
|
19
|
+
"allowScripts": {
|
|
20
|
+
"esbuild": true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
import "../styles/global.css";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
title: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { title, description } = Astro.props;
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<html lang="en">
|
|
13
|
+
<head>
|
|
14
|
+
<meta charset="utf-8" />
|
|
15
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
16
|
+
<title>{title}</title>
|
|
17
|
+
{description && <meta name="description" content={description} />}
|
|
18
|
+
</head>
|
|
19
|
+
<body class="bg-white text-neutral-900 antialiased">
|
|
20
|
+
<header class="mx-auto flex max-w-6xl items-center justify-between px-6 py-6">
|
|
21
|
+
<a href="/" class="font-medium">Site</a>
|
|
22
|
+
<nav class="flex gap-6 text-sm text-neutral-600">
|
|
23
|
+
<a href="/about/" class="hover:text-neutral-900">About</a>
|
|
24
|
+
</nav>
|
|
25
|
+
</header>
|
|
26
|
+
<main class="mx-auto max-w-6xl px-6 pb-24">
|
|
27
|
+
<slot />
|
|
28
|
+
</main>
|
|
29
|
+
</body>
|
|
30
|
+
</html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Layout from "../layouts/Layout.astro";
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<Layout title="About · Site">
|
|
6
|
+
<section class="py-16">
|
|
7
|
+
<h1 class="text-3xl font-semibold tracking-tight">About</h1>
|
|
8
|
+
<p class="mt-4 max-w-xl text-neutral-600">This page is src/pages/about.astro, served at /about/.</p>
|
|
9
|
+
</section>
|
|
10
|
+
</Layout>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Layout from "../layouts/Layout.astro";
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<Layout title="Site" description="A website on Tiniest Cloud.">
|
|
6
|
+
<section class="py-16">
|
|
7
|
+
<h1 class="text-4xl font-semibold tracking-tight">Site</h1>
|
|
8
|
+
<p class="mt-4 max-w-xl text-lg text-neutral-600">Every file in src/pages becomes a page.</p>
|
|
9
|
+
</section>
|
|
10
|
+
</Layout>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";
|