Compare commits
40 Commits
jazz-tools
...
feat/rust-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48279ed642 | ||
|
|
88dbfefd17 | ||
|
|
2939790335 | ||
|
|
48c29435bc | ||
|
|
8668906376 | ||
|
|
6d84e9e83f | ||
|
|
1fea0ef69c | ||
|
|
e4314accb6 | ||
|
|
ee3a4048ef | ||
|
|
9ee1edef3b | ||
|
|
8ab5a09a86 | ||
|
|
2624442903 | ||
|
|
2d199089d5 | ||
|
|
683c170b9d | ||
|
|
518406e23d | ||
|
|
4dcbafa058 | ||
|
|
7ae9e01848 | ||
|
|
dd9ecf660d | ||
|
|
4f849050dc | ||
|
|
681600220f | ||
|
|
384e239ad5 | ||
|
|
54e1a09a46 | ||
|
|
392a9c5aac | ||
|
|
478334eabf | ||
|
|
479f9b0113 | ||
|
|
812622b161 | ||
|
|
8b35fae4b6 | ||
|
|
9e2ecb0378 | ||
|
|
6edd061202 | ||
|
|
865d5385e9 | ||
|
|
a998f94789 | ||
|
|
d17eecfe16 | ||
|
|
8ebfbc86db | ||
|
|
abad8e762f | ||
|
|
037e16392e | ||
|
|
49ac65c123 | ||
|
|
3510fb1273 | ||
|
|
bc3efe7ca0 | ||
|
|
3b06a7809e | ||
|
|
58aa04bb10 |
5
.changeset/shaggy-cycles-carry.md
Normal file
5
.changeset/shaggy-cycles-carry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"create-jazz-app": patch
|
||||
---
|
||||
|
||||
use new svelte starter
|
||||
2
.github/workflows/build-starters.yaml
vendored
2
.github/workflows/build-starters.yaml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
starter: ["react-passkey-auth"]
|
||||
starter: ["react-passkey-auth", "svelte-passkey-auth"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
3
.github/workflows/playwright-homepage.yml
vendored
3
.github/workflows/playwright-homepage.yml
vendored
@@ -22,6 +22,9 @@ jobs:
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Install root dependencies
|
||||
run: pnpm install && pnpm turbo build
|
||||
|
||||
- name: Install project dependencies
|
||||
run: pnpm install
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
1
.github/workflows/playwright.yml
vendored
1
.github/workflows/playwright.yml
vendored
@@ -25,6 +25,7 @@ jobs:
|
||||
"examples/organization",
|
||||
"examples/pets",
|
||||
"starters/react-passkey-auth",
|
||||
"starters/svelte-passkey-auth",
|
||||
"packages/jazz-svelte"
|
||||
]
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"**/android/**",
|
||||
"packages/jazz-svelte/**",
|
||||
"examples/*svelte*/**",
|
||||
"starters/*svelte*/**",
|
||||
"examples/jazz-paper-scissors/src/routeTree.gen.ts",
|
||||
"homepage/homepage/**",
|
||||
"**/package.json"
|
||||
|
||||
@@ -7,16 +7,9 @@ import { Organization } from "../schema.ts";
|
||||
export function InviteLink({
|
||||
organization,
|
||||
}: { organization: Loaded<typeof Organization> }) {
|
||||
const [inviteLink, setInviteLink] = useState<string>();
|
||||
let [copyCount, setCopyCount] = useState(0);
|
||||
let copied = copyCount > 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (organization) {
|
||||
setInviteLink(createInviteLink(organization, "writer"));
|
||||
}
|
||||
}, [organization.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (copyCount > 0) {
|
||||
let timeout = setTimeout(() => setCopyCount(0), 1000);
|
||||
@@ -27,11 +20,10 @@ export function InviteLink({
|
||||
}, [copyCount]);
|
||||
|
||||
const copyUrl = () => {
|
||||
if (inviteLink) {
|
||||
navigator.clipboard.writeText(inviteLink).then(() => {
|
||||
setCopyCount((count) => count + 1);
|
||||
});
|
||||
}
|
||||
const inviteLink = createInviteLink(organization, "writer");
|
||||
navigator.clipboard.writeText(inviteLink).then(() => {
|
||||
setCopyCount((count) => count + 1);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
"jazz-react": "link:../../packages/jazz-react",
|
||||
"jazz-tools": "link:../../packages/jazz-tools",
|
||||
"lucide-react": "^0.436.0",
|
||||
"next": "14.2.7",
|
||||
"next": "15.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"postcss": "^8",
|
||||
"radix-ui": "^1.4.2",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"resend": "^4.0.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
@@ -34,8 +34,8 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@csstools/postcss-oklab-function": "^3.0.6",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@components/*": ["./src/components/*"]
|
||||
}
|
||||
},
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
"persistent": true,
|
||||
"dependsOn": ["^build"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"extends": ["//"]
|
||||
}
|
||||
|
||||
@@ -10,8 +10,15 @@ import { Metadata } from "next";
|
||||
import Image from "next/image";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
type Params = {
|
||||
params: Promise<{
|
||||
slug: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export default async function Post({ params }: Params) {
|
||||
const post = getPostBySlug(params.slug);
|
||||
const { slug } = await params;
|
||||
const post = getPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
return notFound();
|
||||
@@ -65,14 +72,9 @@ export default async function Post({ params }: Params) {
|
||||
);
|
||||
}
|
||||
|
||||
type Params = {
|
||||
params: {
|
||||
slug: string;
|
||||
};
|
||||
};
|
||||
|
||||
export function generateMetadata({ params }: Params): Metadata {
|
||||
const post = getPostBySlug(params.slug);
|
||||
export async function generateMetadata({ params }: Params): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const post = getPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
return notFound();
|
||||
|
||||
@@ -18,15 +18,17 @@ const membersNameToInfoMap = {
|
||||
brad: "Bradley Kowalski",
|
||||
};
|
||||
|
||||
export default function TeamMemberPage({
|
||||
export default async function TeamMemberPage({
|
||||
params,
|
||||
}: { params: { member: string } }) {
|
||||
if (!(params.member in membersNameToInfoMap)) {
|
||||
}: { params: Promise<{ member: string }> }) {
|
||||
const { member } = await params;
|
||||
|
||||
if (!(member in membersNameToInfoMap)) {
|
||||
Router.push("/team");
|
||||
}
|
||||
|
||||
const memberName =
|
||||
membersNameToInfoMap[params.member as keyof typeof membersNameToInfoMap];
|
||||
membersNameToInfoMap[member as keyof typeof membersNameToInfoMap];
|
||||
const memberInfo = team.find(
|
||||
(m: { name: string }) => m.name.toLowerCase() === memberName.toLowerCase(),
|
||||
);
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
"mdast-util-from-markdown": "^2.0.0",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"micromark-extension-mdxjs": "^3.0.0",
|
||||
"next": "14.2.15",
|
||||
"next": "15.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"shiki": "^0.14.6",
|
||||
"shiki-twoslash": "^3.1.2",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
@@ -39,8 +39,8 @@
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"autoprefixer": "^10",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3",
|
||||
|
||||
@@ -6,7 +6,11 @@ export const metadata = {
|
||||
|
||||
# Learn some <span className="sr-only">Jazz</span> <JazzLogo className="h-[41px] -ml-0.5 -mt-[3px] inline" />
|
||||
|
||||
Welcome to the Jazz documentation!
|
||||
**Jazz is a toolkit for building backendless apps**. You get data without needing a database — plus auth, permissions, files and multiplayer without needing a backend. Jazz lets you do everything right from the frontend and you'll ship better apps, faster.
|
||||
|
||||
Instead of wrestling with databases, APIs, and server infrastructure, you work with **CoValues** ("collaborative values") — your new cloud-synced building blocks that feel like local state but automatically sync across all devices and users in real-time.
|
||||
|
||||
---
|
||||
|
||||
**Note:** We just released [Jazz 0.14.0](/docs/upgrade/0-14-0) with a bunch of breaking changes and are still cleaning the docs up - see the [upgrade guide](/docs/upgrade/0-14-0) for details.
|
||||
|
||||
@@ -20,37 +24,44 @@ npx create-jazz-app@latest --api-key you@example.com
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Or set up Jazz yourself, using the following instructions for your framework of choice:
|
||||
|
||||
- [React](/docs/react/project-setup)
|
||||
- [Next.js](/docs/react/project-setup#nextjs)
|
||||
- [React Native](/docs/react-native/project-setup)
|
||||
- [React Native Expo](/docs/react-native-expo/project-setup)
|
||||
- [Vue](/docs/vue/project-setup)
|
||||
- [Svelte](/docs/svelte/project-setup)
|
||||
|
||||
{/* <ContentByFramework framework="react">
|
||||
Or you can follow this [React step-by-step guide](/docs/react/guide) where we walk you through building an issue tracker app.
|
||||
</ContentByFramework> */}
|
||||
|
||||
## Example apps
|
||||
## Why Jazz is different
|
||||
|
||||
You can also find [example apps](/examples) with code most similar to what you want to build. These apps
|
||||
make use of different features such as auth, file upload, and more.
|
||||
Most apps rebuild the same thing: shared state that syncs between users and devices. Jazz starts from that shared state, giving you:
|
||||
|
||||
- **No backend required** — Focus on building features, not infrastructure
|
||||
- **Real-time sync** — Changes appear everywhere immediately
|
||||
- **Multiplayer by default** — Collaboration just works
|
||||
- **Local-first** — Your app works offline and feels instant
|
||||
|
||||
Think Figma, Notion, or Linear — but you don't need years to build a custom stack.
|
||||
|
||||
## How it works
|
||||
|
||||
1. **Define your data** with CoValues schemas
|
||||
2. **Connect to sync infrastructure** (Jazz Cloud or self-hosted)
|
||||
3. **Create and edit CoValues** like normal objects
|
||||
4. **Get automatic sync and persistence** across all devices and users
|
||||
|
||||
Your UI updates instantly on every change, everywhere. It's like having reactive local state that happens to be shared with the world.
|
||||
|
||||
## Ready to see Jazz in action?
|
||||
|
||||
Have a look at our [example apps](/examples) for inspiration and to see what's possible with Jazz. From real-time chat and collaborative editors to file sharing and social features — these are just the beginning of what you can build.
|
||||
|
||||
## Core concepts
|
||||
|
||||
Learn how to structure your data using [collaborative values](/docs/schemas/covalues) — the building blocks that make Jazz apps work.
|
||||
|
||||
## Sync and storage
|
||||
|
||||
Sync and persist your data by setting up a [sync and storage infrastructure](/docs/sync-and-storage) using Jazz Cloud, or do it yourself.
|
||||
Sync and persist your data by setting up [sync and storage infrastructure](/docs/sync-and-storage) using Jazz Cloud, or host it yourself.
|
||||
|
||||
## Collaborative values
|
||||
|
||||
Learn how to structure your data using [collaborative values](/docs/schemas/covalues).
|
||||
|
||||
## LLM Docs
|
||||
## Going deeper
|
||||
|
||||
Get better results with AI by [importing the Jazz docs](/docs/ai-tools) into your context window.
|
||||
|
||||
## Get support
|
||||
|
||||
If you have any questions or need assistance, please don't hesitate to reach out to us on [Discord](https://discord.gg/utDMjHYg42).
|
||||
We would love to help you get started.
|
||||
If you have any questions or need assistance, please don't hesitate to reach out to us on [Discord](https://discord.gg/utDMjHYg42). We'd love to help you get started.
|
||||
|
||||
@@ -253,14 +253,13 @@ Here's a quick overview of the primitive types you can use:
|
||||
|
||||
<CodeGroup>
|
||||
```ts twoslash
|
||||
import {z} from "jazz-tools";
|
||||
// ---cut---
|
||||
z.string(); // For simple strings
|
||||
z.number(); // For numbers
|
||||
import { z } from "jazz-tools";
|
||||
// ---cut---
|
||||
z.string(); // For simple strings
|
||||
z.number(); // For numbers
|
||||
z.boolean(); // For booleans
|
||||
z.null(); // For null
|
||||
z.date(); // For dates
|
||||
z.literal(["waiting", "ready"]); // For enums
|
||||
z.date(); // For dates
|
||||
z.literal(["waiting", "ready"]); // For enums
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ We're introducing a new resolve API for deep loading, more friendly to TypeScrip
|
||||
|
||||
<CodeGroup>
|
||||
```tsx twoslash
|
||||
// @noErrors: 2451
|
||||
// @noErrors: 2451 2769
|
||||
import { CoMap, CoList, coField, Account } from "jazz-tools";
|
||||
import { useAccount } from "jazz-react";
|
||||
class AccountRoot extends CoMap { friends = coField.ref(ListOfAccounts); }
|
||||
|
||||
@@ -84,18 +84,22 @@ function highlightPlugin() {
|
||||
transformers: [
|
||||
transformerTwoslash({
|
||||
explicitTrigger: true,
|
||||
throws: false, //process.env.NODE_ENV === "production",
|
||||
onTwoslashError:
|
||||
process.env.NODE_ENV !== "production"
|
||||
? (e, code) => {
|
||||
const { description, recommendation } = e;
|
||||
console.error("\nTwoslash error: ");
|
||||
console.log(description);
|
||||
console.log(recommendation);
|
||||
console.log("\nCode: \n```\n" + code + "\n```");
|
||||
error = e;
|
||||
}
|
||||
: undefined,
|
||||
throws: process.env.NODE_ENV === "production",
|
||||
onTwoslashError: (e, code) => {
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
// Re-throw to actually fail the build in production
|
||||
throw e;
|
||||
}
|
||||
|
||||
const { description, recommendation } = e;
|
||||
console.error("\nTwoslash error: ");
|
||||
console.log(description);
|
||||
console.log(recommendation);
|
||||
console.log("\nCode: \n```\n" + code + "\n```");
|
||||
|
||||
// In development, store the error to show inline
|
||||
error = e;
|
||||
},
|
||||
}),
|
||||
transformerNotationDiff(),
|
||||
],
|
||||
@@ -103,7 +107,7 @@ function highlightPlugin() {
|
||||
|
||||
node.type = "html";
|
||||
node.value = error
|
||||
? `<div style="color: red;">${error}</div>` + html
|
||||
? `<div style="color: red; background: #fee; padding: 8px; border: 1px solid #fcc; margin: 8px 0;"><strong>Twoslash Error:</strong> ${error.description || error.message} ${error.recommendation}</div>` + html
|
||||
: html;
|
||||
node.children = [];
|
||||
return SKIP;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"@stefanprobst/rehype-extract-toc": "^2.2.0",
|
||||
"@turf/turf": "^7.1.0",
|
||||
"@types/mdx": "^2.0.8",
|
||||
"@types/react-native": "^0.73.0",
|
||||
"@types/topojson-client": "^3.1.5",
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"@vercel/speed-insights": "^1.0.12",
|
||||
@@ -57,8 +58,8 @@
|
||||
"next": "15.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"react-singleton-hook": "^4.0.1",
|
||||
"shiki": "^3.2.1",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
@@ -70,8 +71,8 @@
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@types/geojson": "^7946.0.14",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"autoprefixer": "^10",
|
||||
"pagefind": "^1.3.0",
|
||||
"postcss": "^8",
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
"persistent": true,
|
||||
"dependsOn": ["build"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"extends": ["//"]
|
||||
}
|
||||
|
||||
4169
homepage/pnpm-lock.yaml
generated
4169
homepage/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,10 @@
|
||||
packages:
|
||||
- "homepage"
|
||||
- "design-system"
|
||||
- "gcmp"
|
||||
- "gcmp"
|
||||
|
||||
catalog:
|
||||
"react": "19.0.0"
|
||||
"react-dom": "19.0.0"
|
||||
"@types/react": "19.0.0"
|
||||
"@types/react-dom": "19.0.0"
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"esbuild": "0.24.0"
|
||||
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"expo-router": "patches/expo-router.patch"
|
||||
|
||||
@@ -369,11 +369,9 @@ export class CoValueCore {
|
||||
tryAddTransactions(
|
||||
sessionID: SessionID,
|
||||
newTransactions: Transaction[],
|
||||
givenExpectedNewHash: Hash | undefined,
|
||||
newSignature: Signature,
|
||||
notifyMode: "immediate" | "deferred",
|
||||
skipVerify: boolean = false,
|
||||
givenNewStreamingHash?: StreamingHash,
|
||||
): Result<true, TryAddTransactionsError> {
|
||||
return this.node
|
||||
.resolveAccountAgent(
|
||||
@@ -390,14 +388,12 @@ export class CoValueCore {
|
||||
|
||||
const signerID = this.crypto.getAgentSignerID(agent);
|
||||
|
||||
const result = this.verified.tryAddTransactions(
|
||||
const result = this.verified.tryAdd(
|
||||
sessionID,
|
||||
signerID,
|
||||
newTransactions,
|
||||
givenExpectedNewHash,
|
||||
newSignature,
|
||||
skipVerify,
|
||||
givenNewStreamingHash,
|
||||
);
|
||||
|
||||
if (result.isOk()) {
|
||||
@@ -531,30 +527,33 @@ export class CoValueCore {
|
||||
) as SessionID)
|
||||
: this.node.currentSessionID;
|
||||
|
||||
const { expectedNewHash, newStreamingHash } =
|
||||
this.verified.expectedNewHashAfter(sessionID, [transaction]);
|
||||
const agent = this.node.getCurrentAgent();
|
||||
|
||||
const signature = this.crypto.sign(
|
||||
this.node.getCurrentAgent().currentSignerSecret(),
|
||||
expectedNewHash,
|
||||
this.verified.addNew(
|
||||
sessionID,
|
||||
agent.currentSignerID(),
|
||||
[transaction],
|
||||
agent.currentSignerSecret(),
|
||||
);
|
||||
|
||||
const success = this.tryAddTransactions(
|
||||
sessionID,
|
||||
[transaction],
|
||||
expectedNewHash,
|
||||
signature,
|
||||
"immediate",
|
||||
true,
|
||||
newStreamingHash,
|
||||
)._unsafeUnwrap({ withStackTrace: true });
|
||||
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
||||
void this.node.syncManager.requestCoValueSync(this);
|
||||
|
||||
if (success) {
|
||||
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
||||
void this.node.syncManager.requestCoValueSync(this);
|
||||
if (
|
||||
this._cachedContent &&
|
||||
"processNewTransactions" in this._cachedContent &&
|
||||
typeof this._cachedContent.processNewTransactions === "function"
|
||||
) {
|
||||
this._cachedContent.processNewTransactions();
|
||||
} else {
|
||||
this._cachedContent = undefined;
|
||||
}
|
||||
|
||||
return success;
|
||||
this._cachedDependentOn = undefined;
|
||||
|
||||
this.notifyUpdate("immediate");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getCurrentContent(options?: {
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { Result, err, ok } from "neverthrow";
|
||||
import { AnyRawCoValue } from "../coValue.js";
|
||||
import {
|
||||
APPEND_INVALID_SIGNATURE,
|
||||
APPEND_OK,
|
||||
AppendOnlyVerifiedLog,
|
||||
CryptoProvider,
|
||||
Encrypted,
|
||||
Hash,
|
||||
KeyID,
|
||||
Signature,
|
||||
SignerID,
|
||||
SignerSecret,
|
||||
StreamingHash,
|
||||
} from "../crypto/crypto.js";
|
||||
import { RawCoID, SessionID, TransactionID } from "../ids.js";
|
||||
@@ -48,13 +52,15 @@ export type TrustingTransaction = {
|
||||
|
||||
export type Transaction = PrivateTransaction | TrustingTransaction;
|
||||
|
||||
type SessionLog = {
|
||||
readonly transactions: Transaction[];
|
||||
lastHash?: Hash;
|
||||
streamingHash: StreamingHash;
|
||||
readonly signatureAfter: { [txIdx: number]: Signature | undefined };
|
||||
lastSignature: Signature;
|
||||
};
|
||||
// type SessionLog = {
|
||||
// readonly transactions: Transaction[];
|
||||
// lastHash?: Hash;
|
||||
// streamingHash: StreamingHash;
|
||||
// readonly signatureAfter: { [txIdx: number]: Signature | undefined };
|
||||
// lastSignature: Signature;
|
||||
// };
|
||||
|
||||
type SessionLog = AppendOnlyVerifiedLog<Transaction>;
|
||||
|
||||
export type ValidatedSessions = Map<SessionID, SessionLog>;
|
||||
|
||||
@@ -82,134 +88,47 @@ export class VerifiedState {
|
||||
// do a deep clone, including the sessions
|
||||
const clonedSessions = new Map();
|
||||
for (let [sessionID, sessionLog] of this.sessions) {
|
||||
clonedSessions.set(sessionID, {
|
||||
lastSignature: sessionLog.lastSignature,
|
||||
lastHash: sessionLog.lastHash,
|
||||
streamingHash: sessionLog.streamingHash.clone(),
|
||||
signatureAfter: { ...sessionLog.signatureAfter },
|
||||
transactions: sessionLog.transactions.slice(),
|
||||
} satisfies SessionLog);
|
||||
clonedSessions.set(sessionID, sessionLog.clone());
|
||||
}
|
||||
return new VerifiedState(this.id, this.crypto, this.header, clonedSessions);
|
||||
}
|
||||
|
||||
tryAddTransactions(
|
||||
addNew(
|
||||
sessionID: SessionID,
|
||||
signerID: SignerID,
|
||||
newTransactions: Transaction[],
|
||||
signerSecret: SignerSecret,
|
||||
) {
|
||||
const sessionLog =
|
||||
this.sessions.get(sessionID) ||
|
||||
this.crypto.emptyAppendOnlyVerifiedLog(signerID);
|
||||
sessionLog.addNew(newTransactions, signerSecret);
|
||||
this.sessions.set(sessionID, sessionLog);
|
||||
}
|
||||
|
||||
tryAdd(
|
||||
sessionID: SessionID,
|
||||
signerID: SignerID,
|
||||
newTransactions: Transaction[],
|
||||
givenExpectedNewHash: Hash | undefined,
|
||||
newSignature: Signature,
|
||||
skipVerify: boolean = false,
|
||||
givenNewStreamingHash?: StreamingHash,
|
||||
): Result<true, TryAddTransactionsError> {
|
||||
if (skipVerify === true && givenNewStreamingHash && givenExpectedNewHash) {
|
||||
this.doAddTransactions(
|
||||
sessionID,
|
||||
newTransactions,
|
||||
newSignature,
|
||||
givenExpectedNewHash,
|
||||
givenNewStreamingHash,
|
||||
);
|
||||
const sessionLog =
|
||||
this.sessions.get(sessionID) ||
|
||||
this.crypto.emptyAppendOnlyVerifiedLog(signerID);
|
||||
const result = sessionLog.tryAdd(newTransactions, newSignature, skipVerify);
|
||||
if (result === APPEND_OK) {
|
||||
this.sessions.set(sessionID, sessionLog);
|
||||
return ok(true as const);
|
||||
} else {
|
||||
const { expectedNewHash, newStreamingHash } = this.expectedNewHashAfter(
|
||||
sessionID,
|
||||
newTransactions,
|
||||
);
|
||||
|
||||
if (givenExpectedNewHash && givenExpectedNewHash !== expectedNewHash) {
|
||||
return err({
|
||||
type: "InvalidHash",
|
||||
id: this.id,
|
||||
expectedNewHash,
|
||||
givenExpectedNewHash,
|
||||
} satisfies InvalidHashError);
|
||||
}
|
||||
|
||||
if (!this.crypto.verify(newSignature, expectedNewHash, signerID)) {
|
||||
return err({
|
||||
type: "InvalidSignature",
|
||||
id: this.id,
|
||||
newSignature,
|
||||
sessionID,
|
||||
signerID,
|
||||
} satisfies InvalidSignatureError);
|
||||
}
|
||||
|
||||
this.doAddTransactions(
|
||||
sessionID,
|
||||
newTransactions,
|
||||
return err({
|
||||
type: "InvalidSignature",
|
||||
id: this.id,
|
||||
newSignature,
|
||||
expectedNewHash,
|
||||
newStreamingHash,
|
||||
);
|
||||
sessionID,
|
||||
signerID: sessionLog.signerID,
|
||||
} satisfies InvalidSignatureError);
|
||||
}
|
||||
|
||||
return ok(true as const);
|
||||
}
|
||||
|
||||
private doAddTransactions(
|
||||
sessionID: SessionID,
|
||||
newTransactions: Transaction[],
|
||||
newSignature: Signature,
|
||||
expectedNewHash: Hash,
|
||||
newStreamingHash: StreamingHash,
|
||||
) {
|
||||
const transactions = this.sessions.get(sessionID)?.transactions ?? [];
|
||||
|
||||
for (const tx of newTransactions) {
|
||||
transactions.push(tx);
|
||||
}
|
||||
|
||||
const signatureAfter = this.sessions.get(sessionID)?.signatureAfter ?? {};
|
||||
|
||||
const lastInbetweenSignatureIdx = Object.keys(signatureAfter).reduce(
|
||||
(max, idx) => (parseInt(idx) > max ? parseInt(idx) : max),
|
||||
-1,
|
||||
);
|
||||
|
||||
const sizeOfTxsSinceLastInbetweenSignature = transactions
|
||||
.slice(lastInbetweenSignatureIdx + 1)
|
||||
.reduce(
|
||||
(sum, tx) =>
|
||||
sum +
|
||||
(tx.privacy === "private"
|
||||
? tx.encryptedChanges.length
|
||||
: tx.changes.length),
|
||||
0,
|
||||
);
|
||||
|
||||
if (sizeOfTxsSinceLastInbetweenSignature > MAX_RECOMMENDED_TX_SIZE) {
|
||||
signatureAfter[transactions.length - 1] = newSignature;
|
||||
}
|
||||
|
||||
this.sessions.set(sessionID, {
|
||||
transactions,
|
||||
lastHash: expectedNewHash,
|
||||
streamingHash: newStreamingHash,
|
||||
lastSignature: newSignature,
|
||||
signatureAfter: signatureAfter,
|
||||
});
|
||||
|
||||
this._cachedNewContentSinceEmpty = undefined;
|
||||
this._cachedKnownState = undefined;
|
||||
}
|
||||
|
||||
expectedNewHashAfter(
|
||||
sessionID: SessionID,
|
||||
newTransactions: Transaction[],
|
||||
): { expectedNewHash: Hash; newStreamingHash: StreamingHash } {
|
||||
const streamingHash =
|
||||
this.sessions.get(sessionID)?.streamingHash.clone() ??
|
||||
new StreamingHash(this.crypto);
|
||||
|
||||
for (const transaction of newTransactions) {
|
||||
streamingHash.update(transaction);
|
||||
}
|
||||
|
||||
return {
|
||||
expectedNewHash: streamingHash.digest(),
|
||||
newStreamingHash: streamingHash,
|
||||
};
|
||||
}
|
||||
|
||||
newContentSince(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { base58 } from "@scure/base";
|
||||
import { Transaction } from "../coValueCore/verifiedState.js";
|
||||
import { RawAccountID } from "../coValues/account.js";
|
||||
import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
||||
import { SessionID } from "../ids.js";
|
||||
@@ -297,6 +298,10 @@ export abstract class CryptoProvider<Blake3State = any> {
|
||||
newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
|
||||
return `${accountID}_session_z${base58.encode(this.randomBytes(8))}`;
|
||||
}
|
||||
|
||||
abstract emptyAppendOnlyVerifiedLog<T>(
|
||||
signedID: SignerID,
|
||||
): AppendOnlyVerifiedLog<T>;
|
||||
}
|
||||
|
||||
export type Hash = `hash_z${string}`;
|
||||
@@ -341,3 +346,34 @@ export type KeySecret = `keySecret_z${string}`;
|
||||
export type KeyID = `key_z${string}`;
|
||||
|
||||
export const secretSeedLength = 32;
|
||||
|
||||
export const APPEND_OK = 0;
|
||||
export const APPEND_INVALID_SIGNATURE = 1;
|
||||
|
||||
export type AppendResult = typeof APPEND_OK | typeof APPEND_INVALID_SIGNATURE;
|
||||
|
||||
export interface SessionLog {
|
||||
// these only have to be maintained in JS, anything lower level
|
||||
// only needs to store the encoded items and last streaming hash
|
||||
// and return the new signature on addNew
|
||||
transactions: readonly Transaction[];
|
||||
signerID: SignerID;
|
||||
lastSignature: Signature;
|
||||
signatureAfter: { [txIdx: number]: Signature | undefined };
|
||||
|
||||
clone(): SessionLog;
|
||||
tryAdd(
|
||||
transactions: Transaction[],
|
||||
newSignature: Signature,
|
||||
skipVerify: boolean,
|
||||
): AppendResult;
|
||||
addNewTransaction(changes: JsonValue[], signerSecret: SignerSecret): void;
|
||||
|
||||
// note: this may need to decrypt all transactions since the last decrypted one, even if some of these are invalid
|
||||
// in case we use compression etc.
|
||||
// invariant: we must call this with strictly monotonically increasing txIndex
|
||||
decryptNextTransactionChanges(
|
||||
txIndex: number,
|
||||
keySecret: KeySecret,
|
||||
): JsonValue[] | undefined;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ export const frameworkToAuthExamples: Partial<
|
||||
},
|
||||
"svelte-passkey-auth": {
|
||||
name: "Passkey auth",
|
||||
repo: "garden-co/jazz/examples/passkey-svelte",
|
||||
repo: "garden-co/jazz/starters/svelte-passkey-auth",
|
||||
platform: PLATFORM.WEB,
|
||||
},
|
||||
"rn-minimal-auth": {
|
||||
|
||||
316
pnpm-lock.yaml
generated
316
pnpm-lock.yaml
generated
@@ -1720,7 +1720,7 @@ importers:
|
||||
version: link:../../packages/jazz-tools
|
||||
prosekit:
|
||||
specifier: ^0.13.3
|
||||
version: 0.13.4(@shikijs/types@3.5.0)(@types/hast@3.0.4)(preact@10.25.3)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(solid-js@1.9.5)(svelte@5.33.14)(vue@3.5.13(typescript@5.6.2))
|
||||
version: 0.13.4(@shikijs/types@3.5.0)(@types/hast@3.0.4)(preact@10.25.3)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(solid-js@1.9.5)(svelte@5.33.19)(vue@3.5.13(typescript@5.6.2))
|
||||
react:
|
||||
specifier: 19.0.0
|
||||
version: 19.0.0
|
||||
@@ -3092,6 +3092,76 @@ importers:
|
||||
specifier: ^6.3.5
|
||||
version: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
|
||||
starters/svelte-passkey-auth:
|
||||
dependencies:
|
||||
jazz-inspector-element:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/jazz-inspector-element
|
||||
jazz-svelte:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/jazz-svelte
|
||||
jazz-tools:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/jazz-tools
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.50.1
|
||||
version: 1.50.1
|
||||
'@sveltejs/adapter-auto':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1(@sveltejs/kit@2.21.4(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))
|
||||
'@sveltejs/kit':
|
||||
specifier: ^2.21.4
|
||||
version: 2.21.4(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
'@sveltejs/vite-plugin-svelte':
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
'@types/eslint':
|
||||
specifier: ^9.6.0
|
||||
version: 9.6.1
|
||||
eslint:
|
||||
specifier: ^9.7.0
|
||||
version: 9.17.0(jiti@2.4.2)
|
||||
eslint-config-prettier:
|
||||
specifier: ^9.1.0
|
||||
version: 9.1.0(eslint@9.17.0(jiti@2.4.2))
|
||||
eslint-plugin-svelte:
|
||||
specifier: ^2.36.0
|
||||
version: 2.46.1(eslint@9.17.0(jiti@2.4.2))(svelte@5.33.19)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.18)(typescript@5.6.2))
|
||||
globals:
|
||||
specifier: ^15.11.0
|
||||
version: 15.14.0
|
||||
is-ci:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
postcss:
|
||||
specifier: ^8.4.27
|
||||
version: 8.5.4
|
||||
prettier:
|
||||
specifier: ^3.3.2
|
||||
version: 3.5.3
|
||||
prettier-plugin-svelte:
|
||||
specifier: ^3.2.6
|
||||
version: 3.4.0(prettier@3.5.3)(svelte@5.33.19)
|
||||
svelte:
|
||||
specifier: ^5.33.19
|
||||
version: 5.33.19
|
||||
svelte-check:
|
||||
specifier: ^4.0.0
|
||||
version: 4.1.1(picomatch@4.0.2)(svelte@5.33.19)(typescript@5.6.2)
|
||||
tailwindcss:
|
||||
specifier: ^4.1.7
|
||||
version: 4.1.8
|
||||
typescript:
|
||||
specifier: 5.6.2
|
||||
version: 5.6.2
|
||||
typescript-eslint:
|
||||
specifier: ^8.0.0
|
||||
version: 8.18.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.6.2)
|
||||
vite:
|
||||
specifier: 6.3.5
|
||||
version: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
|
||||
tests/browser-integration:
|
||||
dependencies:
|
||||
cojson:
|
||||
@@ -6953,6 +7023,11 @@ packages:
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': ^2.0.0
|
||||
|
||||
'@sveltejs/adapter-auto@6.0.1':
|
||||
resolution: {integrity: sha512-mcWud3pYGPWM2Pphdj8G9Qiq24nZ8L4LB7coCUckUEy5Y7wOWGJ/enaZ4AtJTcSm5dNK1rIkBRoqt+ae4zlxcQ==}
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': ^2.0.0
|
||||
|
||||
'@sveltejs/adapter-vercel@5.5.2':
|
||||
resolution: {integrity: sha512-6NpumKJ3m9Y6mkSFw4Z8YnaJZc42OWLkSFCk5hD6pLrS4f+b9JVBaXpKB/xkxf1Kf7JpzZtNZKbAaoRrTtJ+Hw==}
|
||||
peerDependencies:
|
||||
@@ -6967,6 +7042,15 @@ packages:
|
||||
svelte: ^4.0.0 || ^5.0.0-next.0
|
||||
vite: ^5.0.3 || ^6.0.0
|
||||
|
||||
'@sveltejs/kit@2.21.4':
|
||||
resolution: {integrity: sha512-683kl4BBnORaYn3vktH01HAHYep8FaiRA21LVY7d6uAX+1D/1gK4WYHRJq90vA01Cz/k6rU3n6vpf4fAn9ipkA==}
|
||||
engines: {node: '>=18.13'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0
|
||||
svelte: ^4.0.0 || ^5.0.0-next.0
|
||||
vite: ^5.0.3 || ^6.0.0
|
||||
|
||||
'@sveltejs/package@2.3.7':
|
||||
resolution: {integrity: sha512-LYgUkde5GUYqOpXbcoCGUpEH4Ctl3Wj4u4CVZBl56dEeLW5fGHE037ZL1qlK0Ky+QD5uUfwONSeGwIOIighFMQ==}
|
||||
engines: {node: ^16.14 || >=18}
|
||||
@@ -6989,6 +7073,13 @@ packages:
|
||||
svelte: ^5.0.0
|
||||
vite: ^6.0.0
|
||||
|
||||
'@sveltejs/vite-plugin-svelte@5.1.0':
|
||||
resolution: {integrity: sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
|
||||
peerDependencies:
|
||||
svelte: ^5.0.0
|
||||
vite: ^6.0.0
|
||||
|
||||
'@swc/core-darwin-arm64@1.10.1':
|
||||
resolution: {integrity: sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -9876,6 +9967,9 @@ packages:
|
||||
esrap@1.4.6:
|
||||
resolution: {integrity: sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==}
|
||||
|
||||
esrap@1.4.9:
|
||||
resolution: {integrity: sha512-3OMlcd0a03UGuZpPeUC1HxR3nA23l+HEyCiZw3b3FumJIN9KphoGzDJKMXI1S72jVS1dsenDyQC0kJlO1U9E1g==}
|
||||
|
||||
esrecurse@4.3.0:
|
||||
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
|
||||
engines: {node: '>=4.0'}
|
||||
@@ -13035,6 +13129,12 @@ packages:
|
||||
prettier: ^3.0.0
|
||||
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
|
||||
|
||||
prettier-plugin-svelte@3.4.0:
|
||||
resolution: {integrity: sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==}
|
||||
peerDependencies:
|
||||
prettier: ^3.0.0
|
||||
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
|
||||
|
||||
prettier-plugin-tailwindcss@0.6.9:
|
||||
resolution: {integrity: sha512-r0i3uhaZAXYP0At5xGfJH876W3HHGHDp+LCRUJrs57PBeQ6mYHMwr25KH8NPX44F2yGTvdnH7OqCshlQx183Eg==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
@@ -14569,6 +14669,10 @@ packages:
|
||||
resolution: {integrity: sha512-kRlbhIlMTijbFmVDQFDeKXPLlX1/ovXwV0I162wRqQhRcygaqDIcu1d/Ese3H2uI+yt3uT8E7ndgDthQv5v5BA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
svelte@5.33.19:
|
||||
resolution: {integrity: sha512-udmgc1nnGeAgnfVJjOMfSOAqPAKv8N65MWN2kDuxo6BZthTaUcsLh4vP8bdZC0bMXLGn69smSZXgQOeuZBOn4Q==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
svg-tags@1.0.0:
|
||||
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
|
||||
|
||||
@@ -15304,6 +15408,14 @@ packages:
|
||||
vite:
|
||||
optional: true
|
||||
|
||||
vitefu@1.0.6:
|
||||
resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==}
|
||||
peerDependencies:
|
||||
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
|
||||
peerDependenciesMeta:
|
||||
vite:
|
||||
optional: true
|
||||
|
||||
vitest@3.1.1:
|
||||
resolution: {integrity: sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
@@ -15966,7 +16078,7 @@ snapshots:
|
||||
'@babel/traverse': 7.27.0
|
||||
'@babel/types': 7.27.0
|
||||
convert-source-map: 2.0.0
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
gensync: 1.0.0-beta.2
|
||||
json5: 2.2.3
|
||||
semver: 6.3.1
|
||||
@@ -17423,7 +17535,7 @@ snapshots:
|
||||
'@babel/parser': 7.26.3
|
||||
'@babel/template': 7.25.9
|
||||
'@babel/types': 7.26.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -17435,7 +17547,7 @@ snapshots:
|
||||
'@babel/parser': 7.27.0
|
||||
'@babel/template': 7.27.0
|
||||
'@babel/types': 7.27.0
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -18076,7 +18188,7 @@ snapshots:
|
||||
'@eslint/eslintrc@2.1.4':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
espree: 9.6.1
|
||||
globals: 13.24.0
|
||||
ignore: 5.3.2
|
||||
@@ -18344,7 +18456,7 @@ snapshots:
|
||||
require-from-string: 2.0.2
|
||||
resolve-from: 5.0.0
|
||||
resolve-workspace-root: 2.0.0
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
slugify: 1.6.6
|
||||
sucrase: 3.35.0
|
||||
transitivePeerDependencies:
|
||||
@@ -18380,7 +18492,7 @@ snapshots:
|
||||
'@expo/env@1.0.5':
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
dotenv: 16.4.7
|
||||
dotenv-expand: 11.0.7
|
||||
getenv: 1.0.0
|
||||
@@ -18492,9 +18604,9 @@ snapshots:
|
||||
'@expo/image-utils': 0.7.4
|
||||
'@expo/json-file': 9.1.4
|
||||
'@react-native/normalize-colors': 0.79.2
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
xml2js: 0.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -18504,7 +18616,7 @@ snapshots:
|
||||
'@expo/server@0.6.2':
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
source-map-support: 0.5.21
|
||||
undici: 6.21.0
|
||||
transitivePeerDependencies:
|
||||
@@ -18603,7 +18715,7 @@ snapshots:
|
||||
'@humanwhocodes/config-array@0.13.0':
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 2.0.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
minimatch: 3.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -19642,15 +19754,15 @@ snapshots:
|
||||
- y-prosemirror
|
||||
- yjs
|
||||
|
||||
'@prosekit/svelte@0.6.9(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(svelte@5.33.14)':
|
||||
'@prosekit/svelte@0.6.9(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(svelte@5.33.19)':
|
||||
dependencies:
|
||||
'@prosekit/core': 0.8.1(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)
|
||||
'@prosekit/pm': 0.1.10
|
||||
'@prosekit/web': 0.5.9(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)
|
||||
'@prosemirror-adapter/core': 0.4.0
|
||||
'@prosemirror-adapter/svelte': 0.4.1(svelte@5.33.14)
|
||||
'@prosemirror-adapter/svelte': 0.4.1(svelte@5.33.19)
|
||||
optionalDependencies:
|
||||
svelte: 5.33.14
|
||||
svelte: 5.33.19
|
||||
transitivePeerDependencies:
|
||||
- '@shikijs/types'
|
||||
- '@types/hast'
|
||||
@@ -19745,13 +19857,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
solid-js: 1.9.5
|
||||
|
||||
'@prosemirror-adapter/svelte@0.4.1(svelte@5.33.14)':
|
||||
'@prosemirror-adapter/svelte@0.4.1(svelte@5.33.19)':
|
||||
dependencies:
|
||||
'@prosemirror-adapter/core': 0.4.0
|
||||
nanoid: 5.0.9
|
||||
tslib: 2.8.1
|
||||
optionalDependencies:
|
||||
svelte: 5.33.14
|
||||
svelte: 5.33.19
|
||||
|
||||
'@prosemirror-adapter/vue@0.4.1(vue@3.5.13(typescript@5.6.2))':
|
||||
dependencies:
|
||||
@@ -20234,7 +20346,7 @@ snapshots:
|
||||
execa: 5.1.1
|
||||
node-stream-zip: 1.15.0
|
||||
ora: 5.4.1
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
strip-ansi: 5.2.0
|
||||
wcwidth: 1.0.1
|
||||
yaml: 2.6.1
|
||||
@@ -20255,7 +20367,7 @@ snapshots:
|
||||
execa: 5.1.1
|
||||
node-stream-zip: 1.15.0
|
||||
ora: 5.4.1
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
strip-ansi: 5.2.0
|
||||
wcwidth: 1.0.1
|
||||
yaml: 2.6.1
|
||||
@@ -20310,7 +20422,7 @@ snapshots:
|
||||
open: 6.4.0
|
||||
ora: 5.4.1
|
||||
prompts: 2.4.2
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
shell-quote: 1.8.2
|
||||
sudo-prompt: 9.1.1
|
||||
|
||||
@@ -21179,6 +21291,10 @@ snapshots:
|
||||
'@sveltejs/kit': 2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
import-meta-resolve: 4.1.0
|
||||
|
||||
'@sveltejs/adapter-auto@6.0.1(@sveltejs/kit@2.21.4(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))':
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.21.4(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
|
||||
'@sveltejs/adapter-vercel@5.5.2(@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(rollup@4.41.1)':
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
@@ -21206,6 +21322,25 @@ snapshots:
|
||||
svelte: 5.33.14
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
|
||||
'@sveltejs/kit@2.21.4(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))':
|
||||
dependencies:
|
||||
'@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1)
|
||||
'@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
'@types/cookie': 0.6.0
|
||||
acorn: 8.14.1
|
||||
cookie: 0.6.0
|
||||
devalue: 5.1.1
|
||||
esm-env: 1.2.2
|
||||
kleur: 4.1.5
|
||||
magic-string: 0.30.17
|
||||
mrmime: 2.0.0
|
||||
sade: 1.8.1
|
||||
set-cookie-parser: 2.7.1
|
||||
sirv: 3.0.1
|
||||
svelte: 5.33.19
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
|
||||
'@sveltejs/package@2.3.7(svelte@5.33.14)(typescript@5.6.2)':
|
||||
dependencies:
|
||||
chokidar: 4.0.3
|
||||
@@ -21220,12 +21355,21 @@ snapshots:
|
||||
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
svelte: 5.33.14
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
debug: 4.4.1
|
||||
svelte: 5.33.19
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.14)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
@@ -21239,6 +21383,19 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)))(svelte@5.33.19)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
debug: 4.4.1
|
||||
deepmerge: 4.3.1
|
||||
kleur: 4.1.5
|
||||
magic-string: 0.30.17
|
||||
svelte: 5.33.19
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@swc/core-darwin-arm64@1.10.1':
|
||||
optional: true
|
||||
|
||||
@@ -22302,8 +22459,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@mapbox/node-pre-gyp': 2.0.0-rc.0
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.41.1)
|
||||
acorn: 8.14.0
|
||||
acorn-import-attributes: 1.9.5(acorn@8.14.0)
|
||||
acorn: 8.14.1
|
||||
acorn-import-attributes: 1.9.5(acorn@8.14.1)
|
||||
async-sema: 3.1.1
|
||||
bindings: 1.5.0
|
||||
estree-walker: 2.0.2
|
||||
@@ -22829,14 +22986,18 @@ snapshots:
|
||||
mime-types: 2.1.35
|
||||
negotiator: 0.6.3
|
||||
|
||||
acorn-import-attributes@1.9.5(acorn@8.14.0):
|
||||
acorn-import-attributes@1.9.5(acorn@8.14.1):
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
acorn: 8.14.1
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.14.1):
|
||||
dependencies:
|
||||
acorn: 8.14.1
|
||||
|
||||
acorn-walk@8.3.2: {}
|
||||
|
||||
acorn-walk@8.3.4:
|
||||
@@ -24458,7 +24619,7 @@ snapshots:
|
||||
eslint-compat-utils@0.5.1(eslint@9.17.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
eslint: 9.17.0(jiti@2.4.2)
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
|
||||
eslint-config-prettier@8.10.0(eslint@8.57.1):
|
||||
dependencies:
|
||||
@@ -24544,6 +24705,25 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
|
||||
eslint-plugin-svelte@2.46.1(eslint@9.17.0(jiti@2.4.2))(svelte@5.33.19)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.18)(typescript@5.6.2)):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@2.4.2))
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
eslint: 9.17.0(jiti@2.4.2)
|
||||
eslint-compat-utils: 0.5.1(eslint@9.17.0(jiti@2.4.2))
|
||||
esutils: 2.0.3
|
||||
known-css-properties: 0.35.0
|
||||
postcss: 8.5.4
|
||||
postcss-load-config: 3.1.4(postcss@8.5.4)(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.18)(typescript@5.6.2))
|
||||
postcss-safe-parser: 6.0.0(postcss@8.5.4)
|
||||
postcss-selector-parser: 6.1.2
|
||||
semver: 7.6.3
|
||||
svelte-eslint-parser: 0.43.0(svelte@5.33.19)
|
||||
optionalDependencies:
|
||||
svelte: 5.33.19
|
||||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
|
||||
eslint-plugin-vue@9.32.0(eslint@9.17.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@2.4.2))
|
||||
@@ -24673,8 +24853,8 @@ snapshots:
|
||||
|
||||
espree@9.6.1:
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
acorn-jsx: 5.3.2(acorn@8.14.0)
|
||||
acorn: 8.14.1
|
||||
acorn-jsx: 5.3.2(acorn@8.14.1)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
esprima@4.0.1: {}
|
||||
@@ -24687,6 +24867,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
esrap@1.4.9:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
esrecurse@4.3.0:
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
@@ -25768,7 +25952,7 @@ snapshots:
|
||||
http-proxy-agent@7.0.2:
|
||||
dependencies:
|
||||
agent-base: 7.1.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -25780,7 +25964,7 @@ snapshots:
|
||||
https-proxy-agent@7.0.6:
|
||||
dependencies:
|
||||
agent-base: 7.1.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -28485,6 +28669,11 @@ snapshots:
|
||||
prettier: 3.4.2
|
||||
svelte: 5.33.14
|
||||
|
||||
prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.33.19):
|
||||
dependencies:
|
||||
prettier: 3.5.3
|
||||
svelte: 5.33.19
|
||||
|
||||
prettier-plugin-tailwindcss@0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.33.14))(prettier@3.4.2):
|
||||
dependencies:
|
||||
prettier: 3.4.2
|
||||
@@ -28553,7 +28742,7 @@ snapshots:
|
||||
|
||||
property-information@7.1.0: {}
|
||||
|
||||
prosekit@0.13.4(@shikijs/types@3.5.0)(@types/hast@3.0.4)(preact@10.25.3)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(solid-js@1.9.5)(svelte@5.33.14)(vue@3.5.13(typescript@5.6.2)):
|
||||
prosekit@0.13.4(@shikijs/types@3.5.0)(@types/hast@3.0.4)(preact@10.25.3)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(solid-js@1.9.5)(svelte@5.33.19)(vue@3.5.13(typescript@5.6.2)):
|
||||
dependencies:
|
||||
'@prosekit/basic': 0.5.1(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)
|
||||
'@prosekit/core': 0.8.1(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)
|
||||
@@ -28563,7 +28752,7 @@ snapshots:
|
||||
'@prosekit/preact': 0.4.14(@shikijs/types@3.5.0)(@types/hast@3.0.4)(preact@10.25.3)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)
|
||||
'@prosekit/react': 0.5.0(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@prosekit/solid': 0.4.14(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(solid-js@1.9.5)
|
||||
'@prosekit/svelte': 0.6.9(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(svelte@5.33.14)
|
||||
'@prosekit/svelte': 0.6.9(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(svelte@5.33.19)
|
||||
'@prosekit/vue': 0.4.14(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)(vue@3.5.13(typescript@5.6.2))
|
||||
'@prosekit/web': 0.5.9(@shikijs/types@3.5.0)(@types/hast@3.0.4)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.4)(prosemirror-view@1.39.2)
|
||||
optionalDependencies:
|
||||
@@ -28571,7 +28760,7 @@ snapshots:
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
solid-js: 1.9.5
|
||||
svelte: 5.33.14
|
||||
svelte: 5.33.19
|
||||
vue: 3.5.13(typescript@5.6.2)
|
||||
transitivePeerDependencies:
|
||||
- '@shikijs/types'
|
||||
@@ -28937,12 +29126,12 @@ snapshots:
|
||||
'@babel/helper-module-imports': 7.25.9
|
||||
'@babel/traverse': 7.26.4
|
||||
'@babel/types': 7.26.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
lightningcss: 1.29.1
|
||||
react: 19.0.0
|
||||
react-native: 0.79.2(@babel/core@7.26.0)(@react-native-community/cli@15.0.1(typescript@5.8.3))(@types/react@19.0.0)(react@19.0.0)
|
||||
react-native-reanimated: 3.17.5(@babel/core@7.26.0)(react-native@0.79.2(@babel/core@7.26.0)(@react-native-community/cli@15.0.1(typescript@5.8.3))(@types/react@19.0.0)(react@19.0.0))(react@19.0.0)
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
tailwindcss: 3.3.2(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.18)(typescript@5.8.3))
|
||||
optionalDependencies:
|
||||
react-native-safe-area-context: 5.4.0(react-native@0.79.2(@babel/core@7.26.0)(@react-native-community/cli@15.0.1(typescript@5.8.3))(@types/react@19.0.0)(react@19.0.0))(react@19.0.0)
|
||||
@@ -28954,12 +29143,12 @@ snapshots:
|
||||
'@babel/helper-module-imports': 7.25.9
|
||||
'@babel/traverse': 7.26.4
|
||||
'@babel/types': 7.26.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
lightningcss: 1.29.1
|
||||
react: 19.0.0
|
||||
react-native: 0.79.2(@babel/core@7.26.0)(@react-native-community/cli@15.0.1(typescript@5.8.3))(@types/react@19.0.0)(react@19.0.0)
|
||||
react-native-reanimated: 3.17.5(@babel/core@7.26.0)(react-native@0.79.2(@babel/core@7.26.0)(@react-native-community/cli@15.0.1(typescript@5.8.3))(@types/react@19.0.0)(react@19.0.0))(react@19.0.0)
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
tailwindcss: 3.4.17(ts-node@10.9.2(@swc/core@1.11.29)(@types/node@22.15.18)(typescript@5.8.3))
|
||||
optionalDependencies:
|
||||
react-native-safe-area-context: 5.4.0(react-native@0.79.2(@babel/core@7.26.0)(@react-native-community/cli@15.0.1(typescript@5.8.3))(@types/react@19.0.0)(react@19.0.0))(react@19.0.0)
|
||||
@@ -29874,7 +30063,7 @@ snapshots:
|
||||
dependencies:
|
||||
color: 4.2.3
|
||||
detect-libc: 2.0.3
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.33.5
|
||||
'@img/sharp-darwin-x64': 0.33.5
|
||||
@@ -30406,6 +30595,18 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- picomatch
|
||||
|
||||
svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.33.19)(typescript@5.6.2):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
chokidar: 4.0.3
|
||||
fdir: 6.4.2(picomatch@4.0.2)
|
||||
picocolors: 1.1.1
|
||||
sade: 1.8.1
|
||||
svelte: 5.33.19
|
||||
typescript: 5.6.2
|
||||
transitivePeerDependencies:
|
||||
- picomatch
|
||||
|
||||
svelte-eslint-parser@0.43.0(svelte@5.33.14):
|
||||
dependencies:
|
||||
eslint-scope: 7.2.2
|
||||
@@ -30416,6 +30617,16 @@ snapshots:
|
||||
optionalDependencies:
|
||||
svelte: 5.33.14
|
||||
|
||||
svelte-eslint-parser@0.43.0(svelte@5.33.19):
|
||||
dependencies:
|
||||
eslint-scope: 7.2.2
|
||||
eslint-visitor-keys: 3.4.3
|
||||
espree: 9.6.1
|
||||
postcss: 8.5.4
|
||||
postcss-scss: 4.0.9(postcss@8.5.4)
|
||||
optionalDependencies:
|
||||
svelte: 5.33.19
|
||||
|
||||
svelte-sonner@0.3.28(svelte@5.33.14):
|
||||
dependencies:
|
||||
svelte: 5.33.14
|
||||
@@ -30444,6 +30655,23 @@ snapshots:
|
||||
magic-string: 0.30.17
|
||||
zimmerframe: 1.1.2
|
||||
|
||||
svelte@5.33.19:
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
'@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1)
|
||||
'@types/estree': 1.0.7
|
||||
acorn: 8.14.1
|
||||
aria-query: 5.3.2
|
||||
axobject-query: 4.1.0
|
||||
clsx: 2.1.1
|
||||
esm-env: 1.2.2
|
||||
esrap: 1.4.9
|
||||
is-reference: 3.0.3
|
||||
locate-character: 3.0.0
|
||||
magic-string: 0.30.17
|
||||
zimmerframe: 1.1.2
|
||||
|
||||
svg-tags@1.0.0: {}
|
||||
|
||||
swr@2.2.5(react@19.0.0):
|
||||
@@ -31223,7 +31451,7 @@ snapshots:
|
||||
vite-node@3.1.1(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
es-module-lexer: 1.6.0
|
||||
pathe: 2.0.3
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
@@ -31285,13 +31513,13 @@ snapshots:
|
||||
dependencies:
|
||||
'@antfu/utils': 0.7.10
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.41.1)
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
error-stack-parser-es: 0.1.5
|
||||
fs-extra: 11.2.0
|
||||
open: 10.1.0
|
||||
perfect-debounce: 1.0.0
|
||||
picocolors: 1.1.1
|
||||
sirv: 3.0.0
|
||||
sirv: 3.0.1
|
||||
vite: 6.3.5(@types/node@22.10.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
@@ -31376,6 +31604,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
|
||||
vitefu@1.0.6(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)):
|
||||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1)
|
||||
|
||||
vitest@3.1.1(@types/node@22.15.18)(@vitest/browser@3.1.1)(@vitest/ui@3.1.1)(happy-dom@17.4.4)(jiti@2.4.2)(jsdom@25.0.1)(lightningcss@1.30.1)(msw@2.7.0(@types/node@22.15.18)(typescript@5.6.2))(terser@5.37.0)(tsx@4.19.3)(yaml@2.6.1):
|
||||
dependencies:
|
||||
'@vitest/expect': 3.1.1
|
||||
@@ -31514,14 +31746,14 @@ snapshots:
|
||||
|
||||
vue-eslint-parser@9.4.3(eslint@9.17.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
debug: 4.4.0
|
||||
debug: 4.4.1
|
||||
eslint: 9.17.0(jiti@2.4.2)
|
||||
eslint-scope: 7.2.2
|
||||
eslint-visitor-keys: 3.4.3
|
||||
espree: 9.6.1
|
||||
esquery: 1.6.0
|
||||
lodash: 4.17.21
|
||||
semver: 7.6.3
|
||||
semver: 7.7.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ const packageJsonFiles = findPackageJsonFiles(rootDir);
|
||||
let hasIssues = false;
|
||||
|
||||
for (const file of packageJsonFiles) {
|
||||
if (file.includes("homepage")) continue;
|
||||
|
||||
const issues = checkCatalogDependencies(file);
|
||||
if (issues.length > 0) {
|
||||
hasIssues = true;
|
||||
|
||||
@@ -41,6 +41,6 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
|
||||
|
||||
## Configuration: sync server
|
||||
|
||||
By default, the app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
|
||||
By default, the React starter app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
|
||||
|
||||
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/Main.tsx](./src/Main.tsx).
|
||||
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/app.tsx](./src/app.tsx) to `{ peer: "ws://localhost:4200" }`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html lang="en" class="h-full">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/favicon.ico" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Jazz | React + Tailwind</title>
|
||||
</head>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||
import { AuthButton } from "./AuthButton.tsx";
|
||||
import { Form } from "./Form.tsx";
|
||||
import { Logo } from "./Logo.tsx";
|
||||
import { AccountRoot, JazzAccount } from "./schema.ts";
|
||||
import { JazzAccount, getUserAge } from "./schema.ts";
|
||||
|
||||
function App() {
|
||||
const { me } = useAccount(JazzAccount, {
|
||||
@@ -32,7 +32,7 @@ function App() {
|
||||
!
|
||||
</h1>
|
||||
{!!me?.root && (
|
||||
<p>As of today, you are {AccountRoot.age(me.root)} years old.</p>
|
||||
<p>As of today, you are {getUserAge(me.root)} years old.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* https://jazz.tools/docs/react/schemas/covalues
|
||||
*/
|
||||
|
||||
import { Group, Loaded, co, z } from "jazz-tools";
|
||||
import { Group, co, z } from "jazz-tools";
|
||||
|
||||
/** The account profile is an app-specific per-user public `CoMap`
|
||||
* where you can store top-level objects for that user */
|
||||
@@ -19,17 +19,14 @@ export const JazzProfile = co.profile({
|
||||
|
||||
/** The account root is an app-specific per-user private `CoMap`
|
||||
* where you can store top-level objects for that user */
|
||||
export const AccountRoot = co
|
||||
.map({
|
||||
dateOfBirth: z.date(),
|
||||
})
|
||||
.withHelpers((Self) => ({
|
||||
// Add helper methods here
|
||||
age(root: Loaded<typeof Self>) {
|
||||
if (!root?.dateOfBirth) return null;
|
||||
return new Date().getFullYear() - root.dateOfBirth.getFullYear();
|
||||
},
|
||||
}));
|
||||
export const AccountRoot = co.map({
|
||||
dateOfBirth: z.date(),
|
||||
});
|
||||
|
||||
export function getUserAge(root: co.loaded<typeof AccountRoot> | undefined) {
|
||||
if (!root) return null;
|
||||
return new Date().getFullYear() - root.dateOfBirth.getFullYear();
|
||||
}
|
||||
|
||||
export const JazzAccount = co
|
||||
.account({
|
||||
|
||||
21
starters/svelte-passkey-auth/.gitignore
vendored
Normal file
21
starters/svelte-passkey-auth/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
node_modules
|
||||
|
||||
# Output
|
||||
.output
|
||||
.vercel
|
||||
/.svelte-kit
|
||||
/build
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# Vite
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
1
starters/svelte-passkey-auth/.npmrc
Normal file
1
starters/svelte-passkey-auth/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
engine-strict=true
|
||||
4
starters/svelte-passkey-auth/.prettierignore
Normal file
4
starters/svelte-passkey-auth/.prettierignore
Normal file
@@ -0,0 +1,4 @@
|
||||
# Package Managers
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
16
starters/svelte-passkey-auth/.prettierrc
Normal file
16
starters/svelte-passkey-auth/.prettierrc
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.svelte",
|
||||
"options": {
|
||||
"parser": "svelte"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
46
starters/svelte-passkey-auth/README.md
Normal file
46
starters/svelte-passkey-auth/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Jazz Svelte starter with Tailwind and Passkey Auth
|
||||
|
||||
A minimal starter template for building apps with **[Jazz](https://jazz.tools)**, Svelte, TailwindCSS, and Passkey Auth.
|
||||
|
||||
## Creating an app
|
||||
|
||||
Create a new Jazz app.
|
||||
|
||||
```bash
|
||||
npx create-jazz-app@latest
|
||||
```
|
||||
|
||||
## Running locally
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
# or
|
||||
yarn
|
||||
```
|
||||
|
||||
Then, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Learning Jazz
|
||||
|
||||
You can start by playing with the form, adding a new field in [./src/lib/schema.ts](./src/lib/schema.ts),
|
||||
and seeing how easy it is to structure your data, and perform basic operations.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
## Configuration: sync server
|
||||
|
||||
By default, the Svelte starter app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
|
||||
|
||||
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzProvider` in [./src/routes/+layout.svelte](./src/routes/+layout.svelte) to `{ peer: "ws://localhost:4200" }`.
|
||||
33
starters/svelte-passkey-auth/eslint.config.js
Normal file
33
starters/svelte-passkey-auth/eslint.config.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import js from "@eslint/js";
|
||||
import prettier from "eslint-config-prettier";
|
||||
import svelte from "eslint-plugin-svelte";
|
||||
import globals from "globals";
|
||||
import ts from "typescript-eslint";
|
||||
|
||||
export default ts.config(
|
||||
js.configs.recommended,
|
||||
...ts.configs.recommended,
|
||||
...svelte.configs["flat/recommended"],
|
||||
prettier,
|
||||
...svelte.configs["flat/prettier"],
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.svelte"],
|
||||
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
parser: ts.parser,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: ["build/", ".svelte-kit/", "dist/"],
|
||||
},
|
||||
);
|
||||
45
starters/svelte-passkey-auth/package.json
Normal file
45
starters/svelte-passkey-auth/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "svelte-passkey-auth",
|
||||
"version": "0.0.89",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "pnpm run check && vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"format": "prettier --write .",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format-and-lint": "pnpm run format && pnpm run lint",
|
||||
"format-and-lint:fix": "pnpm run format --write && pnpm run lint --fix",
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e:ui": "playwright test --ui"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^6.0.1",
|
||||
"@sveltejs/kit": "^2.21.4",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.1.0",
|
||||
"@types/eslint": "^9.6.0",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.36.0",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"postcss": "^8.4.27",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"svelte": "^5.33.19",
|
||||
"svelte-check": "^4.0.0",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"typescript": "5.6.2",
|
||||
"typescript-eslint": "^8.0.0",
|
||||
"vite": "6.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector-element": "workspace:*",
|
||||
"jazz-svelte": "workspace:*",
|
||||
"jazz-tools": "workspace:*"
|
||||
}
|
||||
}
|
||||
46
starters/svelte-passkey-auth/playwright.config.ts
Normal file
46
starters/svelte-passkey-auth/playwright.config.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
import isCI from "is-ci";
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./tests",
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: isCI,
|
||||
/* Retry on CI only */
|
||||
retries: isCI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: isCI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://localhost:5173/",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
permissions: ["clipboard-read", "clipboard-write"],
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: [
|
||||
{
|
||||
command: "pnpm preview --port 5173",
|
||||
url: "http://localhost:5173/",
|
||||
reuseExistingServer: !isCI,
|
||||
},
|
||||
],
|
||||
});
|
||||
5
starters/svelte-passkey-auth/postcss.config.js
Normal file
5
starters/svelte-passkey-auth/postcss.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
1
starters/svelte-passkey-auth/src/apiKey.ts
Normal file
1
starters/svelte-passkey-auth/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const apiKey = "jazz-svelte-starter@garden.co";
|
||||
1
starters/svelte-passkey-auth/src/app.css
Normal file
1
starters/svelte-passkey-auth/src/app.css
Normal file
@@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
13
starters/svelte-passkey-auth/src/app.d.ts
vendored
Normal file
13
starters/svelte-passkey-auth/src/app.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
12
starters/svelte-passkey-auth/src/app.html
Normal file
12
starters/svelte-passkey-auth/src/app.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover" class="p-3 max-w-2xl mx-auto">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
48
starters/svelte-passkey-auth/src/lib/components/Form.svelte
Normal file
48
starters/svelte-passkey-auth/src/lib/components/Form.svelte
Normal file
@@ -0,0 +1,48 @@
|
||||
<script lang="ts">
|
||||
import { JazzAccount } from "$lib/schema";
|
||||
import { AccountCoState } from "jazz-svelte";
|
||||
|
||||
const account = new AccountCoState(JazzAccount, {
|
||||
resolve: {
|
||||
profile: true,
|
||||
root: true,
|
||||
},
|
||||
});
|
||||
const me = $derived(account.current);
|
||||
|
||||
const dateOfBirth = $derived(me ? me.root?.dateOfBirth?.toISOString().split("T")[0] || "" : "");
|
||||
|
||||
function handleDateOfBirthChange(event: Event & { currentTarget: HTMLInputElement }) {
|
||||
if (me && event.currentTarget.value) {
|
||||
me.root.dateOfBirth = new Date(event.currentTarget.value);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if me}
|
||||
<div class="grid gap-4 border p-8 border-stone-200">
|
||||
<div class="flex items-center gap-3">
|
||||
<label for="firstName" class="sm:w-32"> First name </label>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
placeholder="Enter your first name here..."
|
||||
class="border border-stone-300 rounded shadow-xs py-1 px-2 flex-1"
|
||||
bind:value={me.profile.firstName}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<label for="dateOfBirth" class="sm:w-32"> Date of birth </label>
|
||||
<input
|
||||
type="date"
|
||||
id="dateOfBirth"
|
||||
class="border border-stone-300 rounded shadow-xs py-1 px-2 flex-1"
|
||||
value={dateOfBirth}
|
||||
onchange={handleDateOfBirthChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--Add more fields here-->
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,50 @@
|
||||
<script lang="ts">
|
||||
import { JazzAccount } from "$lib/schema";
|
||||
import { usePasskeyAuth } from "jazz-svelte";
|
||||
import { AccountCoState } from "jazz-svelte";
|
||||
|
||||
let { appName } = $props();
|
||||
|
||||
const { logOut } = new AccountCoState(JazzAccount);
|
||||
|
||||
const { current, state } = $derived(
|
||||
usePasskeyAuth({
|
||||
appName,
|
||||
}),
|
||||
);
|
||||
|
||||
const isAuthenticated = $derived(state === "signedIn");
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<nav class="flex justify-between items-center">
|
||||
{#if isAuthenticated}
|
||||
<span>You're logged in.</span>
|
||||
{:else}
|
||||
<span>Authenticate to share the data with another device.</span>
|
||||
{/if}
|
||||
|
||||
{#if isAuthenticated}
|
||||
<button type="button" onclick={logOut} class="bg-stone-100 py-1.5 px-3 text-sm rounded-md">
|
||||
Log out
|
||||
</button>
|
||||
{:else}
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="bg-stone-100 py-1.5 px-3 text-sm rounded-md"
|
||||
onclick={() => current.signUp("")}
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="bg-stone-100 py-1.5 px-3 text-sm rounded-md"
|
||||
onclick={() => current.logIn()}
|
||||
>
|
||||
Log in
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</nav>
|
||||
</header>
|
||||
1
starters/svelte-passkey-auth/src/lib/index.ts
Normal file
1
starters/svelte-passkey-auth/src/lib/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
||||
63
starters/svelte-passkey-auth/src/lib/schema.ts
Normal file
63
starters/svelte-passkey-auth/src/lib/schema.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Learn about schemas here:
|
||||
* https://jazz.tools/docs/svelte/schemas/covalues
|
||||
*/
|
||||
|
||||
import { Group, co, z } from "jazz-tools";
|
||||
|
||||
/** The account profile is an app-specific per-user public `CoMap`
|
||||
* where you can store top-level objects for that user */
|
||||
export const JazzProfile = co.profile({
|
||||
/**
|
||||
* Learn about CoValue field/item types here:
|
||||
* https://jazz.tools/docs/svelte/schemas/covalues#covalue-fielditem-types
|
||||
*/
|
||||
firstName: z.string(),
|
||||
|
||||
// Add public fields here
|
||||
});
|
||||
|
||||
/** The account root is an app-specific per-user private `CoMap`
|
||||
* where you can store top-level objects for that user */
|
||||
export const AccountRoot = co.map({
|
||||
dateOfBirth: z.date(),
|
||||
});
|
||||
|
||||
export function getUserAge(root: co.loaded<typeof AccountRoot> | undefined) {
|
||||
if (!root) return null;
|
||||
return new Date().getFullYear() - root.dateOfBirth.getFullYear();
|
||||
}
|
||||
|
||||
export const JazzAccount = co
|
||||
.account({
|
||||
profile: JazzProfile,
|
||||
root: AccountRoot,
|
||||
})
|
||||
.withMigration(async (account) => {
|
||||
/** The account migration is run on account creation and on every log-in.
|
||||
* You can use it to set up the account root and any other initial CoValues you need.
|
||||
*/
|
||||
if (account.root === undefined) {
|
||||
const group = Group.create();
|
||||
|
||||
account.root = AccountRoot.create(
|
||||
{
|
||||
dateOfBirth: new Date("1/1/1990"),
|
||||
},
|
||||
group,
|
||||
);
|
||||
}
|
||||
|
||||
if (account.profile === undefined) {
|
||||
const group = Group.create();
|
||||
group.addMember("everyone", "reader"); // The profile info is visible to everyone
|
||||
|
||||
account.profile = JazzProfile.create(
|
||||
{
|
||||
name: "",
|
||||
firstName: "",
|
||||
},
|
||||
group,
|
||||
);
|
||||
}
|
||||
});
|
||||
28
starters/svelte-passkey-auth/src/routes/+layout.svelte
Normal file
28
starters/svelte-passkey-auth/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { JazzProvider } from "jazz-svelte";
|
||||
import { apiKey } from "../apiKey";
|
||||
import "../app.css";
|
||||
import Header from "$lib/components/Header.svelte";
|
||||
import "jazz-inspector-element";
|
||||
import { JazzAccount } from "$lib/schema";
|
||||
|
||||
let { children } = $props();
|
||||
let appName = "Jazz Svelte starter";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Jazz | Svelte + Tailwind</title>
|
||||
</svelte:head>
|
||||
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||
}}
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<jazz-inspector></jazz-inspector>
|
||||
<Header {appName} />
|
||||
<main class="max-w-2xl mx-auto px-3 mt-16 flex flex-col gap-8">
|
||||
{@render children?.()}
|
||||
</main>
|
||||
</JazzProvider>
|
||||
42
starters/svelte-passkey-auth/src/routes/+page.svelte
Normal file
42
starters/svelte-passkey-auth/src/routes/+page.svelte
Normal file
@@ -0,0 +1,42 @@
|
||||
<script lang="ts">
|
||||
import Form from "$lib/components/Form.svelte";
|
||||
import { getUserAge, JazzAccount } from "$lib/schema";
|
||||
import { AccountCoState } from "jazz-svelte";
|
||||
|
||||
const account = new AccountCoState(JazzAccount, {
|
||||
resolve: {
|
||||
profile: true,
|
||||
root: true,
|
||||
},
|
||||
});
|
||||
const me = $derived(account.current);
|
||||
</script>
|
||||
|
||||
<div class="text-center">
|
||||
<h1>
|
||||
Welcome{#if me?.profile?.firstName}, {me?.profile.firstName}{/if}!
|
||||
</h1>
|
||||
{#if me?.root}
|
||||
<p>As of today, you are {getUserAge(me?.root)} years old.</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<Form />
|
||||
|
||||
<p class="text-center">
|
||||
Edit the form above,
|
||||
<button type="button" onclick={() => window.location.reload()} class="font-semibold underline">
|
||||
refresh
|
||||
</button>
|
||||
this page, and see your changes persist.
|
||||
</p>
|
||||
|
||||
<p class="text-center">
|
||||
Edit <code class="font-semibold">schema.ts</code> to add more fields.
|
||||
</p>
|
||||
|
||||
<p class="text-center my-16">
|
||||
Go to
|
||||
<a class="font-semibold underline" href="https://jazz.tools/docs"> jazz.tools/docs </a>
|
||||
for our docs.
|
||||
</p>
|
||||
BIN
starters/svelte-passkey-auth/static/favicon.ico
Normal file
BIN
starters/svelte-passkey-auth/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
18
starters/svelte-passkey-auth/svelte.config.js
Normal file
18
starters/svelte-passkey-auth/svelte.config.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import adapter from "@sveltejs/adapter-auto";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://svelte.dev/docs/kit/integrations
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
||||
adapter: adapter(),
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
9
starters/svelte-passkey-auth/tests/page.spec.ts
Normal file
9
starters/svelte-passkey-auth/tests/page.spec.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("home page loads", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await expect(page.getByText("Welcome!")).toBeVisible();
|
||||
|
||||
await page.getByLabel("Name").fill("Bob");
|
||||
await expect(page.getByText("Welcome, Bob!")).toBeVisible();
|
||||
});
|
||||
19
starters/svelte-passkey-auth/tsconfig.json
Normal file
19
starters/svelte-passkey-auth/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
6
starters/svelte-passkey-auth/vite.config.ts
Normal file
6
starters/svelte-passkey-auth/vite.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
});
|
||||
Reference in New Issue
Block a user