jazz-svelte 0.14.23 → 0.14.25

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.
@@ -10,7 +10,7 @@ export function usePasskeyAuth({ appName, appHostname, }) {
10
10
  throw new Error("Passkey auth is not supported in guest mode");
11
11
  }
12
12
  const isAuthenticated = useIsAuthenticated();
13
- const state = $derived(isAuthenticated.value ? "signedIn" : "anonymous");
13
+ const state = $derived(isAuthenticated.current ? "signedIn" : "anonymous");
14
14
  return {
15
15
  current: auth,
16
16
  get state() {
@@ -2,27 +2,27 @@ import { untrack } from "svelte";
2
2
  import { getAuthSecretStorage, getJazzContext } from "../jazz.svelte.js";
3
3
  import { useIsAuthenticated } from "./useIsAuthenticated.svelte.js";
4
4
  import { PassphraseAuth } from "jazz-tools";
5
+ import { createSubscriber } from "svelte/reactivity";
5
6
  /** @category Auth Providers */
6
7
  export function usePassphraseAuth({ wordlist, }) {
7
8
  const context = getJazzContext();
8
9
  const authSecretStorage = getAuthSecretStorage();
9
10
  const auth = new PassphraseAuth(context.current.node.crypto, context.current.authenticate, context.current.register, authSecretStorage, wordlist);
10
- let passphrase = $state(auth.passphrase);
11
- $effect(untrack(() => {
12
- auth.loadCurrentAccountPassphrase();
13
- return auth.subscribe(() => {
14
- passphrase = auth.passphrase;
15
- });
16
- }));
11
+ auth.loadCurrentAccountPassphrase();
12
+ const subscribe = createSubscriber((update) => {
13
+ const off = auth.subscribe(update);
14
+ return () => off();
15
+ });
17
16
  const isAuthenticated = useIsAuthenticated();
18
- const state = $derived(isAuthenticated.value ? "signedIn" : "anonymous");
17
+ const state = $derived(isAuthenticated.current ? "signedIn" : "anonymous");
19
18
  return {
20
19
  logIn: auth.logIn,
21
20
  signUp: auth.signUp,
22
21
  registerNewAccount: auth.registerNewAccount,
23
22
  generateRandomPassphrase: auth.generateRandomPassphrase,
24
23
  get passphrase() {
25
- return passphrase;
24
+ subscribe();
25
+ return auth.passphrase;
26
26
  },
27
27
  get state() {
28
28
  return state;
@@ -1,3 +1,5 @@
1
1
  export declare function useIsAuthenticated(): {
2
+ /** @deprecated Use `current` instead */
2
3
  readonly value: boolean;
4
+ readonly current: boolean;
3
5
  };
@@ -1,17 +1,22 @@
1
+ import { createSubscriber } from "svelte/reactivity";
1
2
  import { getAuthSecretStorage } from "../jazz.svelte.js";
2
- import { onDestroy } from "svelte";
3
3
  export function useIsAuthenticated() {
4
4
  const authSecretStorage = getAuthSecretStorage();
5
- let isAuthenticated = $state(authSecretStorage.isAuthenticated);
6
- const unsubscribe = authSecretStorage.onUpdate(() => {
7
- isAuthenticated = authSecretStorage.isAuthenticated;
8
- });
9
- onDestroy(() => {
10
- unsubscribe();
5
+ const subscribe = createSubscriber((update) => {
6
+ const off = authSecretStorage.onUpdate(update);
7
+ return () => off();
11
8
  });
9
+ function getCurrent() {
10
+ subscribe();
11
+ return authSecretStorage.isAuthenticated;
12
+ }
12
13
  return {
14
+ /** @deprecated Use `current` instead */
13
15
  get value() {
14
- return isAuthenticated;
16
+ return getCurrent();
17
+ },
18
+ get current() {
19
+ return getCurrent();
15
20
  }
16
21
  };
17
22
  }
@@ -14,4 +14,5 @@ export declare class AccountCoState<A extends (AccountClass<Account> & CoValueFr
14
14
  logOut: () => void;
15
15
  get current(): Loaded<A, R> | null | undefined;
16
16
  get agent(): import("jazz-tools").AnonymousJazzAgent | InstanceOfSchema<A>;
17
+ get isAuthenticated(): boolean;
17
18
  }
@@ -1,6 +1,7 @@
1
1
  import { createSubscriber } from 'svelte/reactivity';
2
2
  import { getJazzContext } from './jazz.svelte';
3
3
  import { anySchemaToCoSchema, subscribeToCoValue } from 'jazz-tools';
4
+ import { useIsAuthenticated } from './auth/useIsAuthenticated.svelte.js';
4
5
  export class CoState {
5
6
  #value = undefined;
6
7
  #ctx = getJazzContext();
@@ -8,46 +9,46 @@ export class CoState {
8
9
  #subscribe;
9
10
  constructor(Schema, id, options) {
10
11
  this.#id = $derived.by(typeof id === 'function' ? id : () => id);
11
- this.#subscribe = $derived.by(() => {
12
- const ctx = this.#ctx.current;
13
- const id = this.#id;
14
- if (!ctx || !id)
15
- return;
16
- const agent = 'me' in ctx ? ctx.me : ctx.guest;
17
- return createSubscriber(update => {
18
- const unsubscribe = subscribeToCoValue(anySchemaToCoSchema(Schema), id, {
19
- // @ts-expect-error The resolve query type isn't compatible with the anySchemaToCoSchema conversion
20
- resolve: options?.resolve,
21
- loadAs: agent,
22
- onUnavailable: () => {
23
- this.#value = null;
12
+ this.#subscribe = createSubscriber(update => {
13
+ return $effect.root(() => {
14
+ $effect.pre(() => {
15
+ const ctx = this.#ctx.current;
16
+ const id = this.#id;
17
+ if (!ctx || !id)
18
+ return update();
19
+ const agent = 'me' in ctx ? ctx.me : ctx.guest;
20
+ const unsubscribe = subscribeToCoValue(anySchemaToCoSchema(Schema), id, {
21
+ // @ts-expect-error The resolve query type isn't compatible with the anySchemaToCoSchema conversion
22
+ resolve: options?.resolve,
23
+ loadAs: agent,
24
+ onUnavailable: () => {
25
+ this.#value = null;
26
+ update();
27
+ },
28
+ onUnauthorized: () => {
29
+ this.#value = null;
30
+ update();
31
+ },
32
+ syncResolution: true
33
+ }, value => {
34
+ if (value === this.#value)
35
+ return;
36
+ this.#value = value;
24
37
  update();
25
- },
26
- onUnauthorized: () => {
27
- this.#value = null;
28
- update();
29
- },
30
- syncResolution: true
31
- }, value => {
32
- if (value === this.#value)
33
- return;
34
- this.#value = value;
35
- update();
38
+ });
39
+ return () => {
40
+ unsubscribe();
41
+ this.#value = undefined;
42
+ };
36
43
  });
37
- return () => {
38
- unsubscribe();
39
- this.#value = undefined;
40
- };
41
44
  });
42
45
  });
43
46
  $effect.pre(() => {
44
- if (!this.#id || !this.#ctx.current)
45
- return;
46
- this.#subscribe?.();
47
+ this.#subscribe();
47
48
  });
48
49
  }
49
50
  get current() {
50
- this.#subscribe?.();
51
+ this.#subscribe();
51
52
  return this.#value;
52
53
  }
53
54
  }
@@ -56,49 +57,48 @@ export class AccountCoState {
56
57
  #ctx = getJazzContext();
57
58
  #subscribe;
58
59
  constructor(Schema, options) {
59
- this.#subscribe = $derived.by(() => {
60
- const ctx = this.#ctx.current;
61
- if (!ctx || !('me' in ctx))
62
- return;
63
- const me = ctx.me;
64
- return createSubscriber(update => {
65
- // Setup subscription with current values
66
- const unsubscribe = subscribeToCoValue(anySchemaToCoSchema(Schema), me.id, {
67
- // @ts-expect-error The resolve query type isn't compatible with the anySchemaToCoSchema conversion
68
- resolve: options?.resolve,
69
- loadAs: me,
70
- onUnavailable: () => {
71
- this.#value = null;
72
- update();
73
- },
74
- onUnauthorized: () => {
75
- this.#value = null;
60
+ this.#subscribe = createSubscriber(update => {
61
+ return $effect.root(() => {
62
+ $effect.pre(() => {
63
+ const ctx = this.#ctx.current;
64
+ if (!ctx || !('me' in ctx))
65
+ return update();
66
+ const me = ctx.me;
67
+ const unsubscribe = subscribeToCoValue(anySchemaToCoSchema(Schema), me.id, {
68
+ // @ts-expect-error The resolve query type isn't compatible with the anySchemaToCoSchema conversion
69
+ resolve: options?.resolve,
70
+ loadAs: me,
71
+ onUnavailable: () => {
72
+ this.#value = null;
73
+ update();
74
+ },
75
+ onUnauthorized: () => {
76
+ this.#value = null;
77
+ update();
78
+ },
79
+ syncResolution: true
80
+ }, value => {
81
+ if (value === this.#value)
82
+ return;
83
+ this.#value = value;
76
84
  update();
77
- },
78
- syncResolution: true
79
- }, value => {
80
- if (value === this.#value)
81
- return;
82
- this.#value = value;
83
- update();
85
+ });
86
+ return () => {
87
+ unsubscribe();
88
+ this.#value = undefined;
89
+ };
84
90
  });
85
- return () => {
86
- unsubscribe();
87
- this.#value = undefined;
88
- };
89
91
  });
90
92
  });
91
93
  $effect.pre(() => {
92
- if (!this.#ctx.current)
93
- return;
94
- this.#subscribe?.();
94
+ this.#subscribe();
95
95
  });
96
96
  }
97
97
  logOut = () => {
98
98
  this.#ctx.current?.logOut();
99
99
  };
100
100
  get current() {
101
- this.#subscribe?.();
101
+ this.#subscribe();
102
102
  return this.#value;
103
103
  }
104
104
  get agent() {
@@ -107,4 +107,8 @@ export class AccountCoState {
107
107
  }
108
108
  return 'me' in this.#ctx.current ? this.#ctx.current.me : this.#ctx.current.guest;
109
109
  }
110
+ #isAuthenticated = useIsAuthenticated();
111
+ get isAuthenticated() {
112
+ return this.#isAuthenticated.current;
113
+ }
110
114
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jazz-svelte",
3
- "version": "0.14.23",
3
+ "version": "0.14.25",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",
@@ -46,12 +46,13 @@
46
46
  "svelte-check": "^4.0.0",
47
47
  "typescript": "5.6.2",
48
48
  "typescript-eslint": "^8.0.0",
49
- "vite": "6.3.5"
49
+ "vite": "6.3.5",
50
+ "jazz-inspector-element": "0.14.25"
50
51
  },
51
52
  "dependencies": {
52
- "cojson": "0.14.23",
53
- "jazz-tools": "0.14.23",
54
- "jazz-browser": "0.14.23"
53
+ "cojson": "0.14.25",
54
+ "jazz-tools": "0.14.25",
55
+ "jazz-browser": "0.14.25"
55
56
  },
56
57
  "scripts": {
57
58
  "dev": "vite dev",
@@ -65,6 +66,8 @@
65
66
  "format-and-lint": "pnpm run format && pnpm run lint",
66
67
  "format-and-lint:fix": "pnpm run format --write && pnpm run lint --fix",
67
68
  "test": "vitest",
68
- "test:coverage": "vitest --coverage"
69
+ "test:coverage": "vitest --coverage",
70
+ "test:e2e": "playwright test",
71
+ "test:e2e:ui": "playwright test --ui"
69
72
  }
70
73
  }
@@ -1,32 +0,0 @@
1
- <script lang="ts">
2
- import { CoState } from '../../../jazz.class.svelte.js';
3
- import { Person } from './schema.js';
4
-
5
- let props: { id: string } = $props();
6
-
7
- const person = new CoState(Person, () => props.id, {
8
- resolve: {
9
- dog: true
10
- }
11
- })
12
-
13
- const dogName = $derived(person.current!.dog.name);
14
- </script>
15
-
16
- <!-- Using non-null assertions because we want to test that locally available values are never null -->
17
- <label>
18
- Name
19
- <!-- Jazz values are reactive, but they are not recognized as reactive by Svelte -->
20
- <!-- svelte-ignore binding_property_non_reactive -->
21
- <input type="text" bind:value={person.current!.name} />
22
- </label>
23
-
24
- <label>
25
- Dog
26
- <!-- Jazz values are reactive, but they are not recognized as reactive by Svelte -->
27
- <!-- svelte-ignore binding_property_non_reactive -->
28
- <input type="text" bind:value={person.current!.dog.name} />
29
- </label>
30
-
31
- <div data-testid="person-name">{person.current!.name}</div>
32
- <div data-testid="person-dog-name">{dogName}</div>
@@ -1,6 +0,0 @@
1
- type $$ComponentProps = {
2
- id: string;
3
- };
4
- declare const UpdateNestedValue: import("svelte").Component<$$ComponentProps, {}, "">;
5
- type UpdateNestedValue = ReturnType<typeof UpdateNestedValue>;
6
- export default UpdateNestedValue;
@@ -1,33 +0,0 @@
1
- <script lang="ts">
2
- import { AccountCoState } from '../../../jazz.class.svelte.js';
3
-
4
- import { MyAccount } from './schema.js';
5
-
6
- const me = new AccountCoState(MyAccount, {
7
- resolve: {
8
- root: {
9
- dog: true
10
- }
11
- }
12
- });
13
-
14
- const dogName = $derived(me.current!.root.dog.name);
15
- </script>
16
-
17
- <!-- Using non-null assertions because we want to test that locally available values are never null -->
18
- <label>
19
- Name
20
- <!-- Jazz values are reactive, but they are not recognized as reactive by Svelte -->
21
- <!-- svelte-ignore binding_property_non_reactive -->
22
- <input type="text" bind:value={me.current!.root.name} />
23
- </label>
24
-
25
- <label>
26
- Dog
27
- <!-- Jazz values are reactive, but they are not recognized as reactive by Svelte -->
28
- <!-- svelte-ignore binding_property_non_reactive -->
29
- <input type="text" bind:value={me.current!.root.dog.name} />
30
- </label>
31
-
32
- <div data-testid="person-name">{me.current!.root.name}</div>
33
- <div data-testid="person-dog-name">{dogName}</div>
@@ -1,3 +0,0 @@
1
- declare const UpdateNestedValueAccount: import("svelte").Component<Record<string, never>, {}, "">;
2
- type UpdateNestedValueAccount = ReturnType<typeof UpdateNestedValueAccount>;
3
- export default UpdateNestedValueAccount;
@@ -1,25 +0,0 @@
1
- import { z } from "jazz-tools";
2
- export declare const Dog: import("jazz-tools").CoMapSchema<{
3
- name: z.z.ZodString;
4
- }>;
5
- export declare const Person: import("jazz-tools").CoMapSchema<{
6
- name: z.z.ZodString;
7
- age: z.z.ZodNumber;
8
- dog: import("jazz-tools").CoMapSchema<{
9
- name: z.z.ZodString;
10
- }>;
11
- }>;
12
- export declare const MyAccount: import("jazz-tools").AccountSchema<{
13
- profile: import("jazz-tools/dist/internal").CoProfileSchema<{
14
- name: z.z.core.$ZodString<string>;
15
- inbox?: z.z.core.$ZodOptional<z.z.core.$ZodString>;
16
- inboxInvite?: z.z.core.$ZodOptional<z.z.core.$ZodString>;
17
- }>;
18
- root: import("jazz-tools").CoMapSchema<{
19
- name: z.z.ZodString;
20
- age: z.z.ZodNumber;
21
- dog: import("jazz-tools").CoMapSchema<{
22
- name: z.z.ZodString;
23
- }>;
24
- }>;
25
- }>;
@@ -1,17 +0,0 @@
1
- import { co, z } from "jazz-tools";
2
- export const Dog = co.map({
3
- name: z.string(),
4
- });
5
- export const Person = co.map({
6
- name: z.string(),
7
- age: z.number(),
8
- dog: Dog,
9
- });
10
- export const MyAccount = co.account({
11
- profile: co.profile(),
12
- root: Person,
13
- }).withMigration((account) => {
14
- if (!account._refs.root) {
15
- account.root = Person.create({ name: "John", age: 30, dog: Dog.create({ name: "Rex" }, account) }, account);
16
- }
17
- });
@@ -1,13 +0,0 @@
1
- <script lang="ts">
2
- import { JazzProvider } from "../../jazz.svelte.js";
3
-
4
- const { guestMode } = $props();
5
- </script>
6
-
7
- <div data-testid="provider-test">
8
- <JazzProvider {guestMode} sync={{
9
- peer: "wss://cloud.jazz.tools/?key=jazz-svelte-test"
10
- }}>
11
- <span data-testid="provider-auth-test">Hello</span>
12
- </JazzProvider>
13
- </div>
@@ -1,5 +0,0 @@
1
- declare const ProviderTestComponent: import("svelte").Component<{
2
- guestMode: any;
3
- }, {}, "">;
4
- type ProviderTestComponent = ReturnType<typeof ProviderTestComponent>;
5
- export default ProviderTestComponent;