jazz-tools 0.19.10 → 0.19.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/.turbo/turbo-build.log +53 -49
  2. package/CHANGELOG.md +11 -0
  3. package/dist/{chunk-FFEEPZEG.js → chunk-HX5S6W5E.js} +6 -2
  4. package/dist/chunk-HX5S6W5E.js.map +1 -0
  5. package/dist/index.js +1 -1
  6. package/dist/inspector/account-switcher.d.ts +4 -0
  7. package/dist/inspector/account-switcher.d.ts.map +1 -0
  8. package/dist/inspector/chunk-C6BJPHBQ.js +4096 -0
  9. package/dist/inspector/chunk-C6BJPHBQ.js.map +1 -0
  10. package/dist/inspector/contexts/node.d.ts +19 -0
  11. package/dist/inspector/contexts/node.d.ts.map +1 -0
  12. package/dist/inspector/{custom-element-P76EIWEV.js → custom-element-GJVBPZES.js} +1011 -884
  13. package/dist/inspector/custom-element-GJVBPZES.js.map +1 -0
  14. package/dist/inspector/{viewer/new-app.d.ts → in-app.d.ts} +3 -3
  15. package/dist/inspector/in-app.d.ts.map +1 -0
  16. package/dist/inspector/index.d.ts +0 -11
  17. package/dist/inspector/index.d.ts.map +1 -1
  18. package/dist/inspector/index.js +56 -3910
  19. package/dist/inspector/index.js.map +1 -1
  20. package/dist/inspector/pages/home.d.ts +2 -0
  21. package/dist/inspector/pages/home.d.ts.map +1 -0
  22. package/dist/inspector/register-custom-element.js +1 -1
  23. package/dist/inspector/router/context.d.ts +12 -0
  24. package/dist/inspector/router/context.d.ts.map +1 -0
  25. package/dist/inspector/router/hash-router.d.ts +7 -0
  26. package/dist/inspector/router/hash-router.d.ts.map +1 -0
  27. package/dist/inspector/router/in-memory-router.d.ts +7 -0
  28. package/dist/inspector/router/in-memory-router.d.ts.map +1 -0
  29. package/dist/inspector/router/index.d.ts +5 -0
  30. package/dist/inspector/router/index.d.ts.map +1 -0
  31. package/dist/inspector/standalone.d.ts +6 -0
  32. package/dist/inspector/standalone.d.ts.map +1 -0
  33. package/dist/inspector/standalone.js +420 -0
  34. package/dist/inspector/standalone.js.map +1 -0
  35. package/dist/inspector/tests/router/hash-router.test.d.ts +2 -0
  36. package/dist/inspector/tests/router/hash-router.test.d.ts.map +1 -0
  37. package/dist/inspector/tests/router/in-memory-router.test.d.ts +2 -0
  38. package/dist/inspector/tests/router/in-memory-router.test.d.ts.map +1 -0
  39. package/dist/inspector/ui/modal.d.ts +1 -0
  40. package/dist/inspector/ui/modal.d.ts.map +1 -1
  41. package/dist/inspector/viewer/breadcrumbs.d.ts +1 -7
  42. package/dist/inspector/viewer/breadcrumbs.d.ts.map +1 -1
  43. package/dist/inspector/viewer/header.d.ts +7 -0
  44. package/dist/inspector/viewer/header.d.ts.map +1 -0
  45. package/dist/inspector/viewer/page-stack.d.ts +4 -13
  46. package/dist/inspector/viewer/page-stack.d.ts.map +1 -1
  47. package/dist/inspector/viewer/page.d.ts.map +1 -1
  48. package/dist/testing.js +1 -1
  49. package/dist/tools/coValues/account.d.ts +7 -1
  50. package/dist/tools/coValues/account.d.ts.map +1 -1
  51. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +8 -1
  52. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
  53. package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
  54. package/dist/tools/testing.d.ts.map +1 -1
  55. package/package.json +9 -4
  56. package/src/inspector/account-switcher.tsx +440 -0
  57. package/src/inspector/contexts/node.tsx +129 -0
  58. package/src/inspector/custom-element.tsx +2 -2
  59. package/src/inspector/in-app.tsx +61 -0
  60. package/src/inspector/index.tsx +2 -22
  61. package/src/inspector/pages/home.tsx +77 -0
  62. package/src/inspector/router/context.ts +21 -0
  63. package/src/inspector/router/hash-router.tsx +128 -0
  64. package/src/inspector/{viewer/use-page-path.ts → router/in-memory-router.tsx} +31 -29
  65. package/src/inspector/router/index.ts +4 -0
  66. package/src/inspector/standalone.tsx +60 -0
  67. package/src/inspector/tests/router/hash-router.test.tsx +847 -0
  68. package/src/inspector/tests/router/in-memory-router.test.tsx +724 -0
  69. package/src/inspector/ui/modal.tsx +5 -2
  70. package/src/inspector/viewer/breadcrumbs.tsx +5 -11
  71. package/src/inspector/viewer/header.tsx +67 -0
  72. package/src/inspector/viewer/page-stack.tsx +18 -26
  73. package/src/inspector/viewer/page.tsx +0 -1
  74. package/src/tools/coValues/account.ts +13 -2
  75. package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +8 -1
  76. package/src/tools/tests/account.test.ts +11 -4
  77. package/src/tools/tests/schema.resolved.test.ts +3 -3
  78. package/tsup.config.ts +1 -0
  79. package/dist/chunk-FFEEPZEG.js.map +0 -1
  80. package/dist/inspector/custom-element-P76EIWEV.js.map +0 -1
  81. package/dist/inspector/viewer/new-app.d.ts.map +0 -1
  82. package/dist/inspector/viewer/use-page-path.d.ts +0 -10
  83. package/dist/inspector/viewer/use-page-path.d.ts.map +0 -1
  84. package/src/inspector/viewer/new-app.tsx +0 -156
@@ -15,14 +15,15 @@ interface ModalProps {
15
15
  onCancel?: () => void;
16
16
  showButtons?: boolean;
17
17
  className?: string;
18
+ wide?: boolean;
18
19
  }
19
20
 
20
- const ModalContent = styled("dialog")`
21
+ const ModalContent = styled("dialog")<{ wide?: boolean }>`
21
22
  background-color: var(--j-background);
22
23
  border-radius: var(--j-radius-lg);
23
24
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
24
25
  border: 1px solid var(--j-border-color);
25
- max-width: 32rem;
26
+ ${(props) => (props.wide ? "max-width: 60vw;" : "max-width: 32rem;")}
26
27
  margin-block: auto;
27
28
  margin-inline: auto;
28
29
  &::backdrop {
@@ -90,6 +91,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
90
91
  onCancel,
91
92
  showButtons = true,
92
93
  className,
94
+ wide = false,
93
95
  },
94
96
  ref,
95
97
  ) => {
@@ -123,6 +125,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
123
125
  role="dialog"
124
126
  aria-labelledby="modal-heading"
125
127
  onClose={onClose}
128
+ wide={wide}
126
129
  >
127
130
  <ModalHeader>
128
131
  <Heading id="modal-heading">{heading}</Heading>
@@ -1,7 +1,7 @@
1
1
  import { styled } from "goober";
2
2
  import React from "react";
3
3
  import { Button } from "../ui/button.js";
4
- import { PageInfo } from "./types.js";
4
+ import { useRouter } from "../router/context.js";
5
5
 
6
6
  const BreadcrumbsContainer = styled("div")`
7
7
  position: relative;
@@ -15,21 +15,15 @@ const Separator = styled("span")`
15
15
  padding: 0 0.125rem;
16
16
  `;
17
17
 
18
- interface BreadcrumbsProps {
19
- path: PageInfo[];
20
- onBreadcrumbClick: (index: number) => void;
21
- }
18
+ export const Breadcrumbs: React.FC<{}> = () => {
19
+ const { path, goToIndex } = useRouter();
22
20
 
23
- export const Breadcrumbs: React.FC<BreadcrumbsProps> = ({
24
- path,
25
- onBreadcrumbClick,
26
- }) => {
27
21
  return (
28
22
  <BreadcrumbsContainer>
29
23
  <Button
30
24
  variant="link"
31
25
  style={{ padding: "0 0.25rem" }}
32
- onClick={() => onBreadcrumbClick(-1)}
26
+ onClick={() => goToIndex(-1)}
33
27
  >
34
28
  Home
35
29
  </Button>
@@ -40,7 +34,7 @@ export const Breadcrumbs: React.FC<BreadcrumbsProps> = ({
40
34
  <Button
41
35
  variant="link"
42
36
  style={{ padding: "0 0.25rem" }}
43
- onClick={() => onBreadcrumbClick(index)}
37
+ onClick={() => goToIndex(index)}
44
38
  >
45
39
  {index === 0 ? page.name || "Root" : page.name}
46
40
  </Button>
@@ -0,0 +1,67 @@
1
+ import { CoID, RawCoValue } from "cojson";
2
+ import { styled } from "goober";
3
+ import React, { type PropsWithChildren, useState } from "react";
4
+ import { Button } from "../ui/button.js";
5
+ import { Input } from "../ui/input.js";
6
+ import { Breadcrumbs } from "./breadcrumbs.js";
7
+ import { DeleteLocalData } from "./delete-local-data.js";
8
+ import { useRouter } from "../router/context.js";
9
+
10
+ export function Header({
11
+ showDeleteLocalData = false,
12
+ showClose = false,
13
+ onClose,
14
+ children,
15
+ }: PropsWithChildren<{
16
+ showDeleteLocalData?: boolean;
17
+ showClose?: boolean;
18
+ onClose?: () => void;
19
+ }>) {
20
+ const [coValueId, setCoValueId] = useState<CoID<RawCoValue> | "">("");
21
+ const { path, setPage } = useRouter();
22
+
23
+ const handleCoValueIdSubmit = (e: React.FormEvent) => {
24
+ e.preventDefault();
25
+ if (coValueId) {
26
+ setPage(coValueId);
27
+ }
28
+ setCoValueId("");
29
+ };
30
+
31
+ return (
32
+ <HeaderContainer>
33
+ <Breadcrumbs />
34
+ {path.length !== 0 && (
35
+ <Form onSubmit={handleCoValueIdSubmit}>
36
+ <Input
37
+ label="CoValue ID"
38
+ style={{ fontFamily: "monospace" }}
39
+ hideLabel
40
+ placeholder="co_z1234567890abcdef123456789"
41
+ value={coValueId}
42
+ onChange={(e) => setCoValueId(e.target.value as CoID<RawCoValue>)}
43
+ />
44
+ </Form>
45
+ )}
46
+ {children}
47
+ {showDeleteLocalData && <DeleteLocalData />}
48
+ {showClose && (
49
+ <Button variant="plain" type="button" onClick={onClose}>
50
+ Close
51
+ </Button>
52
+ )}
53
+ </HeaderContainer>
54
+ );
55
+ }
56
+
57
+ const HeaderContainer = styled("div")`
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 1rem;
61
+ padding: 0 0.75rem;
62
+ margin: 0.75rem 0;
63
+ `;
64
+
65
+ const Form = styled("form")`
66
+ width: 24rem;
67
+ `;
@@ -2,23 +2,11 @@ import { CoID, LocalNode, RawCoValue } from "cojson";
2
2
  import { styled } from "goober";
3
3
  import { Page } from "./page.js";
4
4
  import { ErrorBoundary } from "../ui/error-boundary.js";
5
+ import { useRouter } from "../router/context.js";
6
+ import { useNode } from "../contexts/node.js";
7
+ import { HomePage } from "../pages/home.js";
5
8
 
6
- // Define the structure of a page in the path
7
- interface PageInfo {
8
- coId: CoID<RawCoValue>;
9
- name?: string;
10
- }
11
-
12
- // Props for the PageStack component
13
- interface PageStackProps {
14
- path: PageInfo[];
15
- node?: LocalNode | null;
16
- goBack: () => void;
17
- addPages: (pages: PageInfo[]) => void;
18
- children?: React.ReactNode;
19
- }
20
-
21
- const PageStackContainer = styled("div")`
9
+ const PageStackContainer = styled("article")`
22
10
  position: relative;
23
11
  padding: 0 0.75rem;
24
12
  overflow-y: auto;
@@ -27,25 +15,29 @@ const PageStackContainer = styled("div")`
27
15
  font-size: 16px;
28
16
  `;
29
17
 
30
- export function PageStack({
31
- path,
32
- node,
33
- goBack,
34
- addPages,
35
- children,
36
- }: PageStackProps) {
18
+ type PageStackProps = {
19
+ homePage?: React.ReactNode;
20
+ };
21
+
22
+ export function PageStack({ homePage }: PageStackProps) {
23
+ const { path, addPages, goBack } = useRouter();
24
+ const { localNode } = useNode();
25
+
37
26
  const page = path[path.length - 1];
38
27
  const index = path.length - 1;
39
28
 
29
+ if (path.length <= 0) {
30
+ return <PageStackContainer>{homePage ?? <HomePage />}</PageStackContainer>;
31
+ }
32
+
40
33
  return (
41
34
  <>
42
35
  <PageStackContainer>
43
- {children}
44
- {node && page && (
36
+ {localNode && page && (
45
37
  <ErrorBoundary title="An error occurred while rendering this CoValue">
46
38
  <Page
47
39
  coId={page.coId}
48
- node={node}
40
+ node={localNode}
49
41
  name={page.name || page.coId}
50
42
  onHeaderClick={goBack}
51
43
  onNavigate={addPages}
@@ -6,7 +6,6 @@ import {
6
6
  RawCoPlainText,
7
7
  RawCoStream,
8
8
  RawCoValue,
9
- RawGroup,
10
9
  } from "cojson";
11
10
  import { styled } from "goober";
12
11
  import React from "react";
@@ -273,7 +273,13 @@ export class Account extends CoValueBase implements CoValue {
273
273
  creationProps: { name: string };
274
274
  onCreate?: (account: A, worker: Account) => Promise<void>;
275
275
  },
276
- ) {
276
+ ): Promise<{
277
+ credentials: {
278
+ accountID: string;
279
+ accountSecret: AgentSecret;
280
+ };
281
+ account: A;
282
+ }> {
277
283
  const crypto = worker.$jazz.localNode.crypto;
278
284
 
279
285
  const connectedPeers = cojsonInternals.connectedPeers(
@@ -290,6 +296,11 @@ export class Account extends CoValueBase implements CoValue {
290
296
  peers: [connectedPeers[0]],
291
297
  });
292
298
 
299
+ const credentials = {
300
+ accountID: account.$jazz.id,
301
+ accountSecret: account.$jazz.localNode.getCurrentAgent().agentSecret,
302
+ };
303
+
293
304
  // Load the worker inside the account node
294
305
  const loadedWorker = await Account.load(worker.$jazz.id, {
295
306
  loadAs: account,
@@ -314,7 +325,7 @@ export class Account extends CoValueBase implements CoValue {
314
325
  // Close the account node, to avoid leaking memory
315
326
  account.$jazz.localNode.gracefulShutdown();
316
327
 
317
- return createdAccount;
328
+ return { credentials, account: createdAccount };
318
329
  }
319
330
 
320
331
  static fromNode<A extends Account>(
@@ -26,6 +26,7 @@ import {
26
26
  import { CoOptionalSchema } from "./CoOptionalSchema.js";
27
27
  import { CoreResolveQuery } from "./CoValueSchema.js";
28
28
  import { withSchemaResolveQuery } from "../../schemaUtils.js";
29
+ import { AgentSecret } from "cojson";
29
30
 
30
31
  export type BaseProfileShape = {
31
32
  name: z.core.$ZodString<string>;
@@ -103,8 +104,14 @@ export class AccountSchema<
103
104
  worker: Account,
104
105
  ) => Promise<void>;
105
106
  },
107
+ ): Promise<{
108
+ credentials: {
109
+ accountID: string;
110
+ accountSecret: AgentSecret;
111
+ };
106
112
  // @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
107
- ): Promise<Loaded<AccountSchema<Shape>, DefaultResolveQuery>> {
113
+ account: Loaded<AccountSchema<Shape>, DefaultResolveQuery>;
114
+ }> {
108
115
  // @ts-expect-error
109
116
  return this.coValueClass.createAs(worker, options);
110
117
  }
@@ -467,7 +467,7 @@ describe("createAs", () => {
467
467
  { owner: worker },
468
468
  );
469
469
 
470
- const createdAccount = await CustomAccount.createAs(worker, {
470
+ const created = await CustomAccount.createAs(worker, {
471
471
  creationProps: { name: "Test Account" },
472
472
  onCreate: async (account, loadedWorker) => {
473
473
  executionOrder.push("onCreate");
@@ -490,11 +490,18 @@ describe("createAs", () => {
490
490
  },
491
491
  });
492
492
 
493
- assertLoaded(createdAccount);
494
- assertLoaded(createdAccount.root);
493
+ assertLoaded(created.account);
494
+ assertLoaded(created.account.root);
495
+
496
+ expect(created.credentials.accountID).toBe(created.account.$jazz.id);
497
+ // ensure we get the created, not the creat*ing* account credentials
498
+ expect(created.credentials.accountID).not.toBe(worker.$jazz.id);
499
+ expect(created.credentials.accountSecret).not.toBe(
500
+ worker.$jazz.localNode.getCurrentAgent().agentSecret,
501
+ );
495
502
 
496
503
  // Verify onCreate was called and root was set from worker
497
- expect(createdAccount.root.value).toBe("worker-root");
504
+ expect(created.account.root.value).toBe("worker-root");
498
505
 
499
506
  // Verify execution order
500
507
  expect(executionOrder).toEqual(["migration", "onCreate"]);
@@ -246,7 +246,7 @@ describe("Schema.resolved()", () => {
246
246
  profile: true,
247
247
  });
248
248
 
249
- const account = await AccountWithProfile.createAs(serverAccount, {
249
+ const { account } = await AccountWithProfile.createAs(serverAccount, {
250
250
  creationProps: { name: "Hermes Puggington" },
251
251
  onCreate: async (account) => {
252
252
  account.$jazz.set(
@@ -405,7 +405,7 @@ describe("Schema.resolved()", () => {
405
405
  test("for Account", async () => {
406
406
  const AccountWithProfile = co.account().resolved({ profile: true });
407
407
 
408
- const account = await AccountWithProfile.createAs(serverAccount, {
408
+ const { account } = await AccountWithProfile.createAs(serverAccount, {
409
409
  creationProps: { name: "Hermes Puggington" },
410
410
  onCreate: async (account) => {
411
411
  account.$jazz.set(
@@ -561,7 +561,7 @@ describe("Schema.resolved()", () => {
561
561
  .list(TestAccount)
562
562
  .resolved({ $each: TestAccount.resolveQuery });
563
563
 
564
- const account = await TestAccount.createAs(serverAccount, {
564
+ const { account } = await TestAccount.createAs(serverAccount, {
565
565
  creationProps: { name: "Hermes Puggington" },
566
566
  onCreate: async (account) => {
567
567
  account.$jazz.set(
package/tsup.config.ts CHANGED
@@ -58,6 +58,7 @@ export default defineConfig([
58
58
  ...cfg,
59
59
  entry: {
60
60
  index: "src/inspector/index.tsx",
61
+ standalone: "src/inspector/standalone.tsx",
61
62
  },
62
63
  outDir: "dist/inspector",
63
64
  esbuildOptions: (options) => {