@powerhousedao/powerhouse-vetra-packages 6.2.2-dev.76 → 6.2.2-dev.77

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 (41) hide show
  1. package/dist/browser/{connect-2yVh7pKg.js → connect-Dfa445EK.js} +2 -2
  2. package/dist/browser/{connect-2yVh7pKg.js.map → connect-Dfa445EK.js.map} +1 -1
  3. package/dist/browser/{dist-n6WRzvGW.js → dist-Dq_xli8e.js} +1888 -1884
  4. package/dist/browser/dist-Dq_xli8e.js.map +1 -0
  5. package/dist/browser/{editor-BOqgBTL2.js → editor-BVHBckgy.js} +4 -4
  6. package/dist/browser/{editor-BOqgBTL2.js.map → editor-BVHBckgy.js.map} +1 -1
  7. package/dist/browser/{editor-BHS8IZ9o.js → editor-CjtwhcdJ.js} +5 -5
  8. package/dist/browser/{editor-BHS8IZ9o.js.map → editor-CjtwhcdJ.js.map} +1 -1
  9. package/dist/browser/editors/document-model-editor/module.js +1 -1
  10. package/dist/browser/editors/generic-drive-explorer/index.js +3 -3
  11. package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
  12. package/dist/browser/{folder-view-N9lf6Mpv.js → folder-view-DEAGV1EC.js} +3 -3
  13. package/dist/browser/{folder-view-N9lf6Mpv.js.map → folder-view-DEAGV1EC.js.map} +1 -1
  14. package/dist/browser/{graphql-editor-CCabCu2K.js → graphql-editor-CJtKg7XI.js} +2 -2
  15. package/dist/browser/{graphql-editor-CCabCu2K.js.map → graphql-editor-CJtKg7XI.js.map} +1 -1
  16. package/dist/browser/{json-editor-DyNatyzP.js → json-editor-COLbuEyO.js} +2 -2
  17. package/dist/browser/{json-editor-DyNatyzP.js.map → json-editor-COLbuEyO.js.map} +1 -1
  18. package/dist/browser/{state-schemas-sOOHeCL5.js → state-schemas-DIcbtLEN.js} +3 -3
  19. package/dist/browser/{state-schemas-sOOHeCL5.js.map → state-schemas-DIcbtLEN.js.map} +1 -1
  20. package/dist/node/{connect-AGyqHlSg.mjs → connect-BH48bo-2.mjs} +2 -2
  21. package/dist/node/{connect-AGyqHlSg.mjs.map → connect-BH48bo-2.mjs.map} +1 -1
  22. package/dist/node/{dist-Bmp6vCZK.mjs → dist-BzJZJOzf.mjs} +1882 -1878
  23. package/dist/node/dist-BzJZJOzf.mjs.map +1 -0
  24. package/dist/node/{editor-CRFs_N-o.mjs → editor-BfEM_nAZ.mjs} +4 -4
  25. package/dist/node/{editor-CRFs_N-o.mjs.map → editor-BfEM_nAZ.mjs.map} +1 -1
  26. package/dist/node/{editor-DjTKgFi-.mjs → editor-DIpITIp4.mjs} +5 -5
  27. package/dist/node/{editor-DjTKgFi-.mjs.map → editor-DIpITIp4.mjs.map} +1 -1
  28. package/dist/node/editors/document-model-editor/module.mjs +1 -1
  29. package/dist/node/editors/generic-drive-explorer/index.mjs +3 -3
  30. package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
  31. package/dist/node/{folder-view-Bw9lf-FE.mjs → folder-view-CgGhHD-n.mjs} +3 -3
  32. package/dist/node/{folder-view-Bw9lf-FE.mjs.map → folder-view-CgGhHD-n.mjs.map} +1 -1
  33. package/dist/node/{graphql-editor-Bee3v_a1.mjs → graphql-editor-C8N05Tui.mjs} +2 -2
  34. package/dist/node/{graphql-editor-Bee3v_a1.mjs.map → graphql-editor-C8N05Tui.mjs.map} +1 -1
  35. package/dist/node/{json-editor-DkNyMP5s.mjs → json-editor-D0HBH78f.mjs} +2 -2
  36. package/dist/node/{json-editor-DkNyMP5s.mjs.map → json-editor-D0HBH78f.mjs.map} +1 -1
  37. package/dist/node/{state-schemas-DlTrdE-3.mjs → state-schemas-BxV-MnqS.mjs} +3 -3
  38. package/dist/node/{state-schemas-DlTrdE-3.mjs.map → state-schemas-BxV-MnqS.mjs.map} +1 -1
  39. package/package.json +7 -7
  40. package/dist/browser/dist-n6WRzvGW.js.map +0 -1
  41. package/dist/node/dist-Bmp6vCZK.mjs.map +0 -1
@@ -242,777 +242,6 @@ function useDocumentById(id) {
242
242
  const [, dispatch] = useDispatch(document);
243
243
  return [document, dispatch];
244
244
  }
245
- Error;
246
- JSON;
247
- //#endregion
248
- //#region ../reactor-browser/dist/client-DB8gP4hz.js
249
- let DocumentChangeType = /* @__PURE__ */ function(DocumentChangeType) {
250
- DocumentChangeType["ChildAdded"] = "CHILD_ADDED";
251
- DocumentChangeType["ChildRemoved"] = "CHILD_REMOVED";
252
- DocumentChangeType["Created"] = "CREATED";
253
- DocumentChangeType["Deleted"] = "DELETED";
254
- DocumentChangeType["ParentAdded"] = "PARENT_ADDED";
255
- DocumentChangeType["ParentRemoved"] = "PARENT_REMOVED";
256
- DocumentChangeType["Updated"] = "UPDATED";
257
- return DocumentChangeType;
258
- }({});
259
- let PropagationMode = /* @__PURE__ */ function(PropagationMode) {
260
- PropagationMode["Cascade"] = "CASCADE";
261
- PropagationMode["Orphan"] = "ORPHAN";
262
- return PropagationMode;
263
- }({});
264
- const PhDocumentFieldsFragmentDoc = gql`
265
- fragment PHDocumentFields on PHDocument {
266
- id
267
- slug
268
- name
269
- documentType
270
- state
271
- revisionsList {
272
- scope
273
- revision
274
- }
275
- createdAtUtcIso
276
- lastModifiedAtUtcIso
277
- }
278
- `;
279
- gql`
280
- query GetDocumentModels($namespace: String, $paging: PagingInput) {
281
- documentModels(namespace: $namespace, paging: $paging) {
282
- items {
283
- id
284
- name
285
- namespace
286
- version
287
- specification
288
- }
289
- totalCount
290
- hasNextPage
291
- hasPreviousPage
292
- cursor
293
- }
294
- }
295
- `;
296
- const GetDocumentDocument = gql`
297
- query GetDocument($identifier: String!, $view: ViewFilterInput) {
298
- document(identifier: $identifier, view: $view) {
299
- document {
300
- ...PHDocumentFields
301
- }
302
- childIds
303
- }
304
- }
305
- ${PhDocumentFieldsFragmentDoc}
306
- `;
307
- const GetDocumentWithOperationsDocument = gql`
308
- query GetDocumentWithOperations(
309
- $identifier: String!
310
- $view: ViewFilterInput
311
- $operationsFilter: DocumentOperationsFilterInput
312
- $operationsPaging: PagingInput
313
- ) {
314
- document(identifier: $identifier, view: $view) {
315
- document {
316
- ...PHDocumentFields
317
- operations(filter: $operationsFilter, paging: $operationsPaging) {
318
- items {
319
- index
320
- timestampUtcMs
321
- hash
322
- skip
323
- error
324
- deniedReason
325
- id
326
- action {
327
- id
328
- type
329
- timestampUtcMs
330
- input
331
- scope
332
- context {
333
- signer {
334
- user {
335
- address
336
- networkId
337
- chainId
338
- }
339
- app {
340
- name
341
- key
342
- }
343
- signatures
344
- }
345
- }
346
- }
347
- }
348
- totalCount
349
- hasNextPage
350
- hasPreviousPage
351
- cursor
352
- }
353
- }
354
- childIds
355
- }
356
- }
357
- ${PhDocumentFieldsFragmentDoc}
358
- `;
359
- gql`
360
- query GetDocumentOutgoingRelationships(
361
- $sourceIdentifier: String!
362
- $relationshipType: String!
363
- $view: ViewFilterInput
364
- $paging: PagingInput
365
- ) {
366
- documentOutgoingRelationships(
367
- sourceIdentifier: $sourceIdentifier
368
- relationshipType: $relationshipType
369
- view: $view
370
- paging: $paging
371
- ) {
372
- items {
373
- ...PHDocumentFields
374
- }
375
- totalCount
376
- hasNextPage
377
- hasPreviousPage
378
- cursor
379
- }
380
- }
381
- ${PhDocumentFieldsFragmentDoc}
382
- `;
383
- gql`
384
- query GetDocumentIncomingRelationships(
385
- $targetIdentifier: String!
386
- $relationshipType: String!
387
- $view: ViewFilterInput
388
- $paging: PagingInput
389
- ) {
390
- documentIncomingRelationships(
391
- targetIdentifier: $targetIdentifier
392
- relationshipType: $relationshipType
393
- view: $view
394
- paging: $paging
395
- ) {
396
- items {
397
- ...PHDocumentFields
398
- }
399
- totalCount
400
- hasNextPage
401
- hasPreviousPage
402
- cursor
403
- }
404
- }
405
- ${PhDocumentFieldsFragmentDoc}
406
- `;
407
- gql`
408
- query FindDocuments(
409
- $search: SearchFilterInput
410
- $view: ViewFilterInput
411
- $paging: PagingInput
412
- ) {
413
- findDocuments(search: $search, view: $view, paging: $paging) {
414
- items {
415
- ...PHDocumentFields
416
- }
417
- totalCount
418
- hasNextPage
419
- hasPreviousPage
420
- cursor
421
- }
422
- }
423
- ${PhDocumentFieldsFragmentDoc}
424
- `;
425
- const GetDocumentOperationsDocument = gql`
426
- query GetDocumentOperations(
427
- $filter: OperationsFilterInput!
428
- $paging: PagingInput
429
- ) {
430
- documentOperations(filter: $filter, paging: $paging) {
431
- items {
432
- index
433
- timestampUtcMs
434
- hash
435
- skip
436
- error
437
- deniedReason
438
- id
439
- action {
440
- id
441
- type
442
- timestampUtcMs
443
- input
444
- scope
445
- context {
446
- signer {
447
- user {
448
- address
449
- networkId
450
- chainId
451
- }
452
- app {
453
- name
454
- key
455
- }
456
- signatures
457
- }
458
- }
459
- }
460
- }
461
- totalCount
462
- hasNextPage
463
- hasPreviousPage
464
- cursor
465
- }
466
- }
467
- `;
468
- gql`
469
- query GetJobStatus($jobId: String!) {
470
- jobStatus(jobId: $jobId) {
471
- id
472
- status
473
- result
474
- error
475
- createdAt
476
- completedAt
477
- }
478
- }
479
- `;
480
- gql`
481
- query EvaluateActions(
482
- $documentIdentifier: String!
483
- $branch: String
484
- $candidates: [ActionCandidateInput!]!
485
- ) {
486
- evaluateActions(
487
- documentIdentifier: $documentIdentifier
488
- branch: $branch
489
- candidates: $candidates
490
- ) {
491
- evaluations {
492
- decision
493
- reason
494
- }
495
- allAllowed
496
- anyAllowed
497
- allDenied
498
- anyDenied
499
- }
500
- }
501
- `;
502
- gql`
503
- mutation CreateDocument($document: JSONObject!, $parentIdentifier: String) {
504
- createDocument(document: $document, parentIdentifier: $parentIdentifier) {
505
- ...PHDocumentFields
506
- }
507
- }
508
- ${PhDocumentFieldsFragmentDoc}
509
- `;
510
- gql`
511
- mutation CreateEmptyDocument(
512
- $documentType: String!
513
- $parentIdentifier: String
514
- ) {
515
- createEmptyDocument(
516
- documentType: $documentType
517
- parentIdentifier: $parentIdentifier
518
- ) {
519
- ...PHDocumentFields
520
- }
521
- }
522
- ${PhDocumentFieldsFragmentDoc}
523
- `;
524
- gql`
525
- mutation MutateDocument(
526
- $documentIdentifier: String!
527
- $actions: [ActionInput!]!
528
- $branch: String
529
- ) {
530
- mutateDocument: execute(
531
- documentIdentifier: $documentIdentifier
532
- actions: $actions
533
- branch: $branch
534
- ) {
535
- ...PHDocumentFields
536
- }
537
- }
538
- ${PhDocumentFieldsFragmentDoc}
539
- `;
540
- gql`
541
- mutation MutateDocumentAsync(
542
- $documentIdentifier: String!
543
- $actions: [ActionInput!]!
544
- $branch: String
545
- ) {
546
- mutateDocumentAsync: executeAsync(
547
- documentIdentifier: $documentIdentifier
548
- actions: $actions
549
- branch: $branch
550
- ) {
551
- id
552
- status
553
- result
554
- error
555
- createdAt
556
- completedAt
557
- }
558
- }
559
- `;
560
- gql`
561
- mutation RenameDocument(
562
- $documentIdentifier: String!
563
- $name: String!
564
- $branch: String
565
- ) {
566
- renameDocument(
567
- documentIdentifier: $documentIdentifier
568
- name: $name
569
- branch: $branch
570
- ) {
571
- ...PHDocumentFields
572
- }
573
- }
574
- ${PhDocumentFieldsFragmentDoc}
575
- `;
576
- gql`
577
- mutation SetPreferredEditor(
578
- $documentIdentifier: String!
579
- $preferredEditor: String
580
- $branch: String
581
- ) {
582
- setPreferredEditor(
583
- documentIdentifier: $documentIdentifier
584
- preferredEditor: $preferredEditor
585
- branch: $branch
586
- ) {
587
- ...PHDocumentFields
588
- }
589
- }
590
- ${PhDocumentFieldsFragmentDoc}
591
- `;
592
- gql`
593
- mutation AddRelationship(
594
- $sourceIdentifier: String!
595
- $targetIdentifier: String!
596
- $relationshipType: String!
597
- $branch: String
598
- ) {
599
- addRelationship(
600
- sourceIdentifier: $sourceIdentifier
601
- targetIdentifier: $targetIdentifier
602
- relationshipType: $relationshipType
603
- branch: $branch
604
- ) {
605
- ...PHDocumentFields
606
- }
607
- }
608
- ${PhDocumentFieldsFragmentDoc}
609
- `;
610
- gql`
611
- mutation RemoveRelationship(
612
- $sourceIdentifier: String!
613
- $targetIdentifier: String!
614
- $relationshipType: String!
615
- $branch: String
616
- ) {
617
- removeRelationship(
618
- sourceIdentifier: $sourceIdentifier
619
- targetIdentifier: $targetIdentifier
620
- relationshipType: $relationshipType
621
- branch: $branch
622
- ) {
623
- ...PHDocumentFields
624
- }
625
- }
626
- ${PhDocumentFieldsFragmentDoc}
627
- `;
628
- gql`
629
- mutation MoveRelationship(
630
- $sourceParentIdentifier: String!
631
- $targetParentIdentifier: String!
632
- $targetIdentifier: String!
633
- $relationshipType: String!
634
- $branch: String
635
- ) {
636
- moveRelationship(
637
- sourceParentIdentifier: $sourceParentIdentifier
638
- targetParentIdentifier: $targetParentIdentifier
639
- targetIdentifier: $targetIdentifier
640
- relationshipType: $relationshipType
641
- branch: $branch
642
- ) {
643
- source {
644
- ...PHDocumentFields
645
- }
646
- target {
647
- ...PHDocumentFields
648
- }
649
- }
650
- }
651
- ${PhDocumentFieldsFragmentDoc}
652
- `;
653
- gql`
654
- mutation DeleteDocument($identifier: String!, $propagate: PropagationMode) {
655
- deleteDocument(identifier: $identifier, propagate: $propagate)
656
- }
657
- `;
658
- gql`
659
- mutation DeleteDocuments(
660
- $identifiers: [String!]!
661
- $propagate: PropagationMode
662
- ) {
663
- deleteDocuments(identifiers: $identifiers, propagate: $propagate)
664
- }
665
- `;
666
- gql`
667
- subscription DocumentChanges(
668
- $search: SearchFilterInput
669
- $view: ViewFilterInput
670
- ) {
671
- documentChanges(search: $search, view: $view) {
672
- type
673
- documents {
674
- ...PHDocumentFields
675
- }
676
- context {
677
- parentId
678
- childId
679
- }
680
- }
681
- }
682
- ${PhDocumentFieldsFragmentDoc}
683
- `;
684
- gql`
685
- subscription JobChanges($jobId: String!) {
686
- jobChanges(jobId: $jobId) {
687
- jobId
688
- status
689
- result
690
- error
691
- }
692
- }
693
- `;
694
- gql`
695
- query PollSyncEnvelopes(
696
- $channelId: String!
697
- $outboxAck: Int!
698
- $outboxLatest: Int!
699
- ) {
700
- pollSyncEnvelopes(
701
- channelId: $channelId
702
- outboxAck: $outboxAck
703
- outboxLatest: $outboxLatest
704
- ) {
705
- envelopes {
706
- type
707
- channelMeta {
708
- id
709
- }
710
- operations {
711
- operation {
712
- index
713
- timestampUtcMs
714
- hash
715
- skip
716
- error
717
- deniedReason
718
- id
719
- action {
720
- id
721
- type
722
- timestampUtcMs
723
- input
724
- scope
725
- context {
726
- signer {
727
- user {
728
- address
729
- networkId
730
- chainId
731
- }
732
- app {
733
- name
734
- key
735
- }
736
- signatures
737
- }
738
- }
739
- }
740
- }
741
- context {
742
- documentId
743
- documentType
744
- scope
745
- branch
746
- }
747
- }
748
- cursor {
749
- remoteName
750
- cursorOrdinal
751
- lastSyncedAtUtcMs
752
- }
753
- key
754
- dependsOn
755
- }
756
- ackOrdinal
757
- deadLetters {
758
- documentId
759
- error
760
- errorType
761
- }
762
- hasMore
763
- }
764
- }
765
- `;
766
- gql`
767
- mutation TouchChannel($input: TouchChannelInput!) {
768
- touchChannel(input: $input) {
769
- success
770
- ackOrdinal
771
- }
772
- }
773
- `;
774
- gql`
775
- mutation PushSyncEnvelopes($envelopes: [SyncEnvelopeInput!]!) {
776
- pushSyncEnvelopes(envelopes: $envelopes)
777
- }
778
- `;
779
- /** Get the source string from a GraphQL document (string or DocumentNode). */
780
- function getDocumentSource(doc) {
781
- return typeof doc === "string" ? doc : doc.loc?.source.body ?? "";
782
- }
783
- /**
784
- * Extract the inner selection set of a named field from a GraphQL document source.
785
- * Returns the `{ ... }` block including braces.
786
- */
787
- function extractSelectionSet(doc, fieldName, fallback) {
788
- const source = getDocumentSource(doc);
789
- return new RegExp(`${fieldName}\\([^)]*\\)\\s*(\\{[\\s\\S]*\\})\\s*\\}`).exec(source)?.[1] ?? fallback;
790
- }
791
- /**
792
- * Extract the query body and any fragment definitions from a GraphQL document.
793
- * Returns { body, fragments } where body is the content inside the query `{ ... }`
794
- * and fragments are any trailing fragment definitions.
795
- */
796
- function extractQueryParts(doc, fallbackBody) {
797
- const source = getDocumentSource(doc);
798
- const queryMatch = /^[^{]*\{([\s\S]*?)\}\s*(fragment[\s\S]*)?$/.exec(source);
799
- return {
800
- body: queryMatch?.[1]?.trim() ?? fallbackBody,
801
- fragments: queryMatch?.[2]?.trim() ?? ""
802
- };
803
- }
804
- extractSelectionSet(GetDocumentOperationsDocument, "documentOperations", "{ items { index } }");
805
- extractQueryParts(GetDocumentDocument, "document(identifier: $identifier) { document { id name documentType state revisionsList { scope revision } createdAtUtcIso lastModifiedAtUtcIso } childIds }");
806
- //#endregion
807
- //#region ../reactor-browser/dist/renown-6w_ImTvm.js
808
- const { useValue: useLoading, setValue: setLoading, addEventHandler: addLoadingEventHandler } = makePHEventFunctions("loading");
809
- const RenownInitialUserContext = createContext({ state: "unknown" });
810
- /** First-render auth as a three-state value; use this to skip a spinner when anonymous. */
811
- function useRenownInitialAuth() {
812
- return useContext(RenownInitialUserContext);
813
- }
814
- function useRenownInitialUser() {
815
- const initial = useRenownInitialAuth();
816
- return initial.state === "authenticated" ? initial.user : void 0;
817
- }
818
- const renownEventFunctions = makePHEventFunctions("renown");
819
- renownEventFunctions.addEventHandler;
820
- /** Returns the renown instance */
821
- const useRenown = renownEventFunctions.useValue;
822
- renownEventFunctions.setValue;
823
- function jsonEqual(a, b) {
824
- if (a === b) return true;
825
- if (typeof a !== "object" || typeof b !== "object" || !a || !b) return false;
826
- if (Array.isArray(a) !== Array.isArray(b)) return false;
827
- const ra = a;
828
- const rb = b;
829
- const keys = Object.keys(ra).filter((k) => ra[k] !== void 0);
830
- if (keys.length !== Object.keys(rb).filter((k) => rb[k] !== void 0).length) return false;
831
- return keys.every((k) => jsonEqual(ra[k], rb[k]));
832
- }
833
- function sameUser(a, b) {
834
- return jsonEqual(a, b);
835
- }
836
- function resolveInstanceUser(instance, seed) {
837
- const restored = instance.user;
838
- if (restored) return sameUser(seed, restored) ? seed : restored;
839
- return instance.status === "initial" ? void 0 : seed;
840
- }
841
- /** Returns the current user from the renown instance, subscribing to user events */
842
- function useUser() {
843
- const renown = useRenown();
844
- const initialUser = useRenownInitialUser();
845
- const instance = renown ? renown : void 0;
846
- const [tracked, setTracked] = useState(() => ({
847
- instance,
848
- user: instance ? resolveInstanceUser(instance, initialUser) : initialUser
849
- }));
850
- const current = tracked.instance === instance ? tracked : {
851
- instance,
852
- user: instance ? resolveInstanceUser(instance, tracked.user ?? initialUser) : tracked.user
853
- };
854
- useEffect(() => {
855
- if (current !== tracked) setTracked(current);
856
- }, [current, tracked]);
857
- useEffect(() => {
858
- if (!instance) return;
859
- return instance.on("user", (user) => setTracked((prev) => ({
860
- instance,
861
- user: sameUser(prev.user, user) ? prev.user : user
862
- })));
863
- }, [instance]);
864
- return instance ? current.user : initialUser ?? current.user;
865
- }
866
- //#endregion
867
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/lazyDataLastImpl-DtF3cihj.js
868
- function e$8(e, t, n) {
869
- let r = (n) => e(n, ...t);
870
- return n === void 0 ? r : Object.assign(r, {
871
- lazy: n,
872
- lazyArgs: t
873
- });
874
- }
875
- //#endregion
876
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/purry.js
877
- function t$5(t, n, r) {
878
- let i = t.length - n.length;
879
- if (i === 0) return t(...n);
880
- if (i === 1) return e$8(t, n, r);
881
- throw Error(`Wrong number of arguments`);
882
- }
883
- //#endregion
884
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/allPass.js
885
- function t$4(...t) {
886
- return t$5(n$4, t);
887
- }
888
- const n$4 = (e, t) => t.every((t) => t(e));
889
- //#endregion
890
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/conditional-CTEJD5TX.js
891
- function e$7(e, t, n) {
892
- return e(n[0]) ? (e) => t(e, ...n) : t(...n);
893
- }
894
- function t$3(...t) {
895
- return e$7(r, n$3, t);
896
- }
897
- function n$3(e, ...t) {
898
- for (let n of t) {
899
- if (typeof n == `function`) return n(e);
900
- let [t, r] = n;
901
- if (t(e)) return r(e);
902
- }
903
- throw Error(`conditional: data failed for all cases`);
904
- }
905
- function r(e) {
906
- if (!Array.isArray(e)) return !1;
907
- let [t, n, ...r] = e;
908
- return typeof t == `function` && t.length <= 1 && typeof n == `function` && n.length <= 1 && r.length === 0;
909
- }
910
- //#endregion
911
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/constant.js
912
- function e$6(e) {
913
- return () => e;
914
- }
915
- //#endregion
916
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/hasAtLeast.js
917
- function t$2(...t) {
918
- return t$5(n$2, t);
919
- }
920
- const n$2 = (e, t) => e.length >= t;
921
- //#endregion
922
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/funnel.js
923
- const e$5 = Symbol(`funnel/voidReducer`), t$1 = () => e$5;
924
- function n$1(n, { triggerAt: r = `end`, minQuietPeriodMs: i, maxBurstDurationMs: a, minGapMs: o, reducer: s = t$1 }) {
925
- let c, l, u, d, f = () => {
926
- let t = u;
927
- t !== void 0 && (u = void 0, t === e$5 ? n() : n(t), o !== void 0 && (l = setTimeout(p, o)));
928
- }, p = () => {
929
- clearTimeout(l), l = void 0, c === void 0 && f();
930
- }, m = () => {
931
- clearTimeout(c), c = void 0, d = void 0, l === void 0 && f();
932
- };
933
- return {
934
- call: (...e) => {
935
- let t = c === void 0 && l === void 0;
936
- if ((r !== `start` || t) && (u = s(u, ...e)), !(c === void 0 && !t)) {
937
- if (i !== void 0 || a !== void 0 || o === void 0) {
938
- clearTimeout(c);
939
- let e = Date.now();
940
- d ??= e;
941
- let t = a === void 0 ? i ?? 0 : Math.min(i ?? a, Math.max(0, a - (e - d)));
942
- c = setTimeout(m, t);
943
- }
944
- r !== `end` && t && f();
945
- }
946
- },
947
- cancel: () => {
948
- clearTimeout(c), c = void 0, d = void 0, clearTimeout(l), l = void 0, u = void 0;
949
- },
950
- flush: () => {
951
- m(), p();
952
- },
953
- get isIdle() {
954
- return c === void 0 && l === void 0;
955
- }
956
- };
957
- }
958
- //#endregion
959
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isDefined.js
960
- function e$4(e) {
961
- return e !== void 0;
962
- }
963
- //#endregion
964
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isNot.js
965
- function e$3(e) {
966
- return (t) => !e(t);
967
- }
968
- //#endregion
969
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isStrictEqual.js
970
- function t(...t) {
971
- return t$5(n, t);
972
- }
973
- const n = (e, t) => e === t || Object.is(e, t);
974
- //#endregion
975
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isString.js
976
- function e$2(e) {
977
- return typeof e == `string`;
978
- }
979
- //#endregion
980
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isTruthy.js
981
- function e$1(e) {
982
- return !!e;
983
- }
984
- //#endregion
985
- //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/once.js
986
- function e(e) {
987
- let t = !1, n;
988
- return () => (t ||= (n = e(), !0), n);
989
- }
990
- var CloseCode = /* @__PURE__ */ ((CloseCode2) => {
991
- CloseCode2[CloseCode2["InternalServerError"] = 4500] = "InternalServerError";
992
- CloseCode2[CloseCode2["InternalClientError"] = 4005] = "InternalClientError";
993
- CloseCode2[CloseCode2["BadRequest"] = 4400] = "BadRequest";
994
- CloseCode2[CloseCode2["BadResponse"] = 4004] = "BadResponse";
995
- CloseCode2[CloseCode2["Unauthorized"] = 4401] = "Unauthorized";
996
- CloseCode2[CloseCode2["Forbidden"] = 4403] = "Forbidden";
997
- CloseCode2[CloseCode2["SubprotocolNotAcceptable"] = 4406] = "SubprotocolNotAcceptable";
998
- CloseCode2[CloseCode2["ConnectionInitialisationTimeout"] = 4408] = "ConnectionInitialisationTimeout";
999
- CloseCode2[CloseCode2["ConnectionAcknowledgementTimeout"] = 4504] = "ConnectionAcknowledgementTimeout";
1000
- CloseCode2[CloseCode2["SubscriberAlreadyExists"] = 4409] = "SubscriberAlreadyExists";
1001
- CloseCode2[CloseCode2["TooManyInitialisationRequests"] = 4429] = "TooManyInitialisationRequests";
1002
- return CloseCode2;
1003
- })(CloseCode || {});
1004
- var MessageType = /* @__PURE__ */ ((MessageType2) => {
1005
- MessageType2["ConnectionInit"] = "connection_init";
1006
- MessageType2["ConnectionAck"] = "connection_ack";
1007
- MessageType2["Ping"] = "ping";
1008
- MessageType2["Pong"] = "pong";
1009
- MessageType2["Subscribe"] = "subscribe";
1010
- MessageType2["Next"] = "next";
1011
- MessageType2["Error"] = "error";
1012
- MessageType2["Complete"] = "complete";
1013
- return MessageType2;
1014
- })(MessageType || {});
1015
- Error;
1016
245
  //#endregion
1017
246
  //#region ../../node_modules/.pnpm/slug@11.0.1/node_modules/slug/slug.js
1018
247
  let base64;
@@ -1800,7 +1029,7 @@ slug.setLocale = function(locale) {
1800
1029
  defaultLocale = locales[locale] || {};
1801
1030
  };
1802
1031
  //#endregion
1803
- //#region ../reactor-browser/dist/document-operations-DZ-oUHRy.js
1032
+ //#region ../reactor-browser/dist/document-model-modules-BB9s6a3m.js
1804
1033
  var UnsupportedDocumentTypeError = class extends Error {
1805
1034
  constructor(documentType) {
1806
1035
  super(`Document type ${documentType} is not supported`);
@@ -1826,1082 +1055,1921 @@ var DocumentTypeMismatchError = class extends Error {
1826
1055
  super(`Document ${documentId} is not of type ${expectedType}. Actual type: ${actualType}`);
1827
1056
  }
1828
1057
  };
1829
- var NoSelectedDocumentError = class extends Error {
1830
- constructor() {
1831
- super("There is no selected document. Did you mean to call 'useSelectedDocumentSafe' instead?");
1058
+ var NoSelectedDocumentError = class extends Error {
1059
+ constructor() {
1060
+ super("There is no selected document. Did you mean to call 'useSelectedDocumentSafe' instead?");
1061
+ }
1062
+ };
1063
+ function resolveUrlPathname(path) {
1064
+ return new URL(path.replace(/^\/+/, ""), window.location.origin + (window.ph?.basePath ?? "/")).pathname;
1065
+ }
1066
+ /** Returns the current path without the base path */
1067
+ function getPathWithoutBase(path) {
1068
+ const basePath = window.ph?.basePath ?? "/";
1069
+ return path.replace(basePath, basePath.endsWith("/") ? "/" : "");
1070
+ }
1071
+ /** Makes a URL component for a node. */
1072
+ function makeNodeSlug(node) {
1073
+ if (!node) return "";
1074
+ const nodeName = node.name;
1075
+ if (!nodeName) return slug(node.id);
1076
+ return slug(`${nodeName}-${node.id}`);
1077
+ }
1078
+ /** Extracts the node slug from a path.
1079
+ *
1080
+ * The path is expected to be in the format `/d/<drive-slug>/<node-slug>`.
1081
+ */
1082
+ function extractNodeSlugFromPath(path) {
1083
+ const currentPath = getPathWithoutBase(path);
1084
+ return /^\/d\/[^/]+\/([^/]+)$/.exec(currentPath)?.[1];
1085
+ }
1086
+ /** Finds a UUID in a string, used for extracting node ids from node slugs in the URL. */
1087
+ function findUuid(input) {
1088
+ if (!input) return void 0;
1089
+ return /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/.exec(input)?.[0];
1090
+ }
1091
+ function extractNodeIdFromSlug(nodeSlug) {
1092
+ return findUuid(nodeSlug);
1093
+ }
1094
+ /** Extracts the drive slug from a path.
1095
+ * Used for extracting drive ids from drive slugs in the URL.
1096
+ * Expects the path to be in the format `/d/<drive-slug>`.
1097
+ */
1098
+ function extractDriveSlugFromPath(path) {
1099
+ const currentPath = getPathWithoutBase(path);
1100
+ return /^\/d\/([^/]+)/.exec(currentPath)?.[1] ?? "";
1101
+ }
1102
+ /**
1103
+ * Creates a URL string with the given pathname while preserving existing query parameters.
1104
+ */
1105
+ function createUrlWithPreservedParams(pathname) {
1106
+ const search = window.location.search;
1107
+ return search ? `${pathname}${search}` : pathname;
1108
+ }
1109
+ const drivesEventFunctions = makePHEventFunctions("drives");
1110
+ /** Returns all of the drives in the reactor */
1111
+ const useDrives = drivesEventFunctions.useValue;
1112
+ /** Sets the drives in the reactor */
1113
+ const setDrives = drivesEventFunctions.setValue;
1114
+ drivesEventFunctions.addEventHandler;
1115
+ const selectedNodeIdEventFunctions = makePHEventFunctions("selectedNodeId");
1116
+ const useSelectedNodeId = selectedNodeIdEventFunctions.useValue;
1117
+ const setSelectedNodeId = selectedNodeIdEventFunctions.setValue;
1118
+ selectedNodeIdEventFunctions.addEventHandler;
1119
+ /** Sets the selected node (file or folder). */
1120
+ function setSelectedNode(nodeOrNodeSlug) {
1121
+ const nodeSlug = typeof nodeOrNodeSlug === "string" ? nodeOrNodeSlug : makeNodeSlug(nodeOrNodeSlug);
1122
+ setSelectedNodeId(extractNodeIdFromSlug(nodeSlug));
1123
+ const driveSlugFromPath = extractDriveSlugFromPath(window.location.pathname);
1124
+ if (!driveSlugFromPath) return;
1125
+ if (!nodeSlug) {
1126
+ const pathname = resolveUrlPathname(`/d/${driveSlugFromPath}`);
1127
+ if (pathname === window.location.pathname) return;
1128
+ window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
1129
+ return;
1130
+ }
1131
+ const pathname = resolveUrlPathname(`/d/${driveSlugFromPath}/${nodeSlug}`);
1132
+ if (pathname === window.location.pathname) return;
1133
+ window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
1134
+ }
1135
+ const selectedDriveIdEventFunctions = makePHEventFunctions("selectedDriveId");
1136
+ /** Returns the selected drive id */
1137
+ const useSelectedDriveId = selectedDriveIdEventFunctions.useValue;
1138
+ /** Sets the selected drive id */
1139
+ const setSelectedDriveId = selectedDriveIdEventFunctions.setValue;
1140
+ selectedDriveIdEventFunctions.addEventHandler;
1141
+ /** Returns the selected drive, or undefined if no drive is selected */
1142
+ function useSelectedDriveSafe() {
1143
+ const selectedDriveId = useSelectedDriveId();
1144
+ const selectedDrive = useDrives()?.find((drive) => drive.header.id === selectedDriveId);
1145
+ const [drive, dispatch] = useDispatch(selectedDrive);
1146
+ if (!selectedDrive) return [void 0, void 0];
1147
+ return [drive, dispatch];
1148
+ }
1149
+ function setSelectedDrive(driveOrDriveSlug) {
1150
+ const driveSlug = typeof driveOrDriveSlug === "string" ? driveOrDriveSlug : driveOrDriveSlug?.header.slug;
1151
+ const drives = window.ph?.drives;
1152
+ const driveId = (typeof driveOrDriveSlug === "object" && driveOrDriveSlug !== null ? driveOrDriveSlug : drives?.find((d) => d.header.slug === driveSlug))?.header.id;
1153
+ if (!driveId && driveSlug && extractDriveSlugFromPath(window.location.pathname) === driveSlug) {
1154
+ if (window.ph?.selectedDriveId) setSelectedDriveId(void 0);
1155
+ deferDriveSelection(driveSlug);
1156
+ return;
1157
+ }
1158
+ cancelPendingDriveSelection();
1159
+ setSelectedDriveId(driveId);
1160
+ if (!driveId) {
1161
+ const pathname = resolveUrlPathname("/");
1162
+ if (pathname === window.location.pathname) return;
1163
+ window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
1164
+ return;
1165
+ }
1166
+ const pathname = resolveUrlPathname(`/d/${driveSlug}`);
1167
+ if (pathname === window.location.pathname) return;
1168
+ window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
1169
+ }
1170
+ const DEFERRED_DRIVE_TICK_MS = 2e3;
1171
+ const DEFERRED_DRIVE_MAX_WAIT_MS = 15e3;
1172
+ function isInitialSyncInFlight() {
1173
+ const remotes = window.ph?.reactorClientModule?.reactorModule?.syncModule?.syncManager?.list();
1174
+ if (!remotes?.length) return false;
1175
+ return remotes.some((remote) => {
1176
+ try {
1177
+ const snapshot = remote.channel.getConnectionState();
1178
+ return snapshot.receivingPages || !snapshot.lastSuccessUtcMs && snapshot.state !== "error";
1179
+ } catch {
1180
+ return false;
1181
+ }
1182
+ });
1183
+ }
1184
+ let pendingHandler;
1185
+ let pendingTimeout;
1186
+ function cancelPendingDriveSelection() {
1187
+ if (pendingHandler) {
1188
+ window.removeEventListener("ph:drivesUpdated", pendingHandler);
1189
+ pendingHandler = void 0;
1190
+ }
1191
+ if (pendingTimeout) {
1192
+ clearTimeout(pendingTimeout);
1193
+ pendingTimeout = void 0;
1194
+ }
1195
+ }
1196
+ function deferDriveSelection(driveSlug) {
1197
+ cancelPendingDriveSelection();
1198
+ const nodeSlug = extractNodeSlugFromPath(window.location.pathname);
1199
+ const handler = () => {
1200
+ if (!window.ph?.drives?.find((d) => d.header.slug === driveSlug)) return;
1201
+ cancelPendingDriveSelection();
1202
+ setSelectedDrive(driveSlug);
1203
+ setSelectedNode(nodeSlug);
1204
+ };
1205
+ pendingHandler = handler;
1206
+ window.addEventListener("ph:drivesUpdated", handler);
1207
+ const deadline = Date.now() + DEFERRED_DRIVE_MAX_WAIT_MS;
1208
+ const scheduleTick = () => {
1209
+ pendingTimeout = setTimeout(() => {
1210
+ if (Date.now() < deadline && isInitialSyncInFlight()) {
1211
+ scheduleTick();
1212
+ return;
1213
+ }
1214
+ cancelPendingDriveSelection();
1215
+ const pathname = resolveUrlPathname("/");
1216
+ if (pathname === window.location.pathname) return;
1217
+ window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
1218
+ }, DEFERRED_DRIVE_TICK_MS);
1219
+ };
1220
+ scheduleTick();
1221
+ }
1222
+ /** Sorts nodes by name. */
1223
+ function sortNodesByName(nodes) {
1224
+ return nodes.toSorted((a, b) => a.name.localeCompare(b.name));
1225
+ }
1226
+ /** Returns whether a node is a file. */
1227
+ function isFileNodeKind(node) {
1228
+ if (!node) return false;
1229
+ return node.kind.toUpperCase() === "FILE";
1230
+ }
1231
+ /** Returns whether a node is a folder. */
1232
+ function isFolderNodeKind(node) {
1233
+ if (!node) return false;
1234
+ return node.kind.toUpperCase() === "FOLDER";
1235
+ }
1236
+ /** Returns the nodes in the selected drive. */
1237
+ function useNodesInSelectedDrive() {
1238
+ const [selectedDrive] = useSelectedDriveSafe();
1239
+ return selectedDrive?.state.global.nodes;
1240
+ }
1241
+ /** Returns the folder nodes in the selected drive. */
1242
+ function useFolderNodesInSelectedDrive() {
1243
+ return useNodesInSelectedDrive()?.filter((n) => isFolderNodeKind(n));
1244
+ }
1245
+ /** Returns the selected node. */
1246
+ function useSelectedNode() {
1247
+ const selectedNodeId = useSelectedNodeId();
1248
+ return useNodesInSelectedDrive()?.find((n) => n.id === selectedNodeId);
1249
+ }
1250
+ const vetraPackageManagerFunctions = makePHEventFunctions("vetraPackageManager");
1251
+ const useVetraPackageManager = vetraPackageManagerFunctions.useValue;
1252
+ /** Returns all of the Vetra packages loaded by the Connect instance */
1253
+ const useVetraPackages = () => {
1254
+ const packageManager = useVetraPackageManager();
1255
+ return useSyncExternalStore((cb) => packageManager ? packageManager.subscribe(cb) : () => {}, () => packageManager?.packages ?? []);
1256
+ };
1257
+ vetraPackageManagerFunctions.addEventHandler;
1258
+ function useDocumentModelModules() {
1259
+ return useVetraPackages().flatMap((pkg) => pkg.documentModels).filter((module, index, modules) => modules.findIndex((m) => m.documentModel.global.id === module.documentModel.global.id && m.version === module.version) === index);
1260
+ }
1261
+ /**
1262
+ * Resolves a document model module by document type, mirroring the registry's
1263
+ * semantics (`IDocumentModelRegistry.getModule`): with `version` omitted the
1264
+ * LATEST version of the type wins (`version ?? 1` as each module's default),
1265
+ * with `version` given only an exact match is returned. The reactor resolves
1266
+ * modules the same way when a document is created, so metadata read through
1267
+ * this hook and the version a creation actually uses cannot disagree.
1268
+ */
1269
+ function useDocumentModelModuleById(id, version) {
1270
+ const documentModelModules = useDocumentModelModules();
1271
+ if (!id || !documentModelModules) return void 0;
1272
+ let latestModule;
1273
+ let latestVersion = -1;
1274
+ for (const module of documentModelModules) {
1275
+ if (module.documentModel.global.id !== id) continue;
1276
+ const moduleVersion = module.version ?? 1;
1277
+ if (version !== void 0) {
1278
+ if (moduleVersion === version) return module;
1279
+ continue;
1280
+ }
1281
+ if (moduleVersion > latestVersion) {
1282
+ latestVersion = moduleVersion;
1283
+ latestModule = module;
1284
+ }
1832
1285
  }
1833
- };
1834
- const modalEventFunctions = makePHEventFunctions("modal");
1835
- modalEventFunctions.useValue;
1836
- /** Sets the current modal */
1837
- const setPHModal = modalEventFunctions.setValue;
1838
- modalEventFunctions.addEventHandler;
1839
- /** Shows a modal */
1840
- function showPHModal(modal) {
1841
- setPHModal(modal);
1286
+ return latestModule;
1842
1287
  }
1843
- /** Shows the delete node modal */
1844
- function showDeleteNodeModal(nodeOrId) {
1845
- setPHModal({
1846
- type: "deleteItem",
1847
- id: typeof nodeOrId === "string" ? nodeOrId : nodeOrId.id
1848
- });
1288
+ Error;
1289
+ JSON;
1290
+ //#endregion
1291
+ //#region ../reactor-browser/dist/client-D66jVnot.js
1292
+ let DocumentChangeType = /* @__PURE__ */ function(DocumentChangeType) {
1293
+ DocumentChangeType["ChildAdded"] = "CHILD_ADDED";
1294
+ DocumentChangeType["ChildRemoved"] = "CHILD_REMOVED";
1295
+ DocumentChangeType["Created"] = "CREATED";
1296
+ DocumentChangeType["Deleted"] = "DELETED";
1297
+ DocumentChangeType["ParentAdded"] = "PARENT_ADDED";
1298
+ DocumentChangeType["ParentRemoved"] = "PARENT_REMOVED";
1299
+ DocumentChangeType["Updated"] = "UPDATED";
1300
+ return DocumentChangeType;
1301
+ }({});
1302
+ let PropagationMode = /* @__PURE__ */ function(PropagationMode) {
1303
+ PropagationMode["Cascade"] = "CASCADE";
1304
+ PropagationMode["Orphan"] = "ORPHAN";
1305
+ return PropagationMode;
1306
+ }({});
1307
+ const PhDocumentFieldsFragmentDoc = gql`
1308
+ fragment PHDocumentFields on PHDocument {
1309
+ id
1310
+ slug
1311
+ name
1312
+ documentType
1313
+ state
1314
+ revisionsList {
1315
+ scope
1316
+ revision
1317
+ }
1318
+ createdAtUtcIso
1319
+ lastModifiedAtUtcIso
1320
+ }
1321
+ `;
1322
+ gql`
1323
+ query GetDocumentModels($namespace: String, $paging: PagingInput) {
1324
+ documentModels(namespace: $namespace, paging: $paging) {
1325
+ items {
1326
+ id
1327
+ name
1328
+ namespace
1329
+ version
1330
+ specification
1331
+ }
1332
+ totalCount
1333
+ hasNextPage
1334
+ hasPreviousPage
1335
+ cursor
1336
+ }
1337
+ }
1338
+ `;
1339
+ const GetDocumentDocument = gql`
1340
+ query GetDocument($identifier: String!, $view: ViewFilterInput) {
1341
+ document(identifier: $identifier, view: $view) {
1342
+ document {
1343
+ ...PHDocumentFields
1344
+ }
1345
+ childIds
1346
+ }
1347
+ }
1348
+ ${PhDocumentFieldsFragmentDoc}
1349
+ `;
1350
+ const GetDocumentWithOperationsDocument = gql`
1351
+ query GetDocumentWithOperations(
1352
+ $identifier: String!
1353
+ $view: ViewFilterInput
1354
+ $operationsFilter: DocumentOperationsFilterInput
1355
+ $operationsPaging: PagingInput
1356
+ ) {
1357
+ document(identifier: $identifier, view: $view) {
1358
+ document {
1359
+ ...PHDocumentFields
1360
+ operations(filter: $operationsFilter, paging: $operationsPaging) {
1361
+ items {
1362
+ index
1363
+ timestampUtcMs
1364
+ hash
1365
+ skip
1366
+ error
1367
+ deniedReason
1368
+ id
1369
+ action {
1370
+ id
1371
+ type
1372
+ timestampUtcMs
1373
+ input
1374
+ scope
1375
+ context {
1376
+ signer {
1377
+ user {
1378
+ address
1379
+ networkId
1380
+ chainId
1381
+ }
1382
+ app {
1383
+ name
1384
+ key
1385
+ }
1386
+ signatures
1387
+ }
1388
+ }
1389
+ }
1390
+ }
1391
+ totalCount
1392
+ hasNextPage
1393
+ hasPreviousPage
1394
+ cursor
1395
+ }
1396
+ }
1397
+ childIds
1398
+ }
1399
+ }
1400
+ ${PhDocumentFieldsFragmentDoc}
1401
+ `;
1402
+ gql`
1403
+ query GetDocumentOutgoingRelationships(
1404
+ $sourceIdentifier: String!
1405
+ $relationshipType: String!
1406
+ $view: ViewFilterInput
1407
+ $paging: PagingInput
1408
+ ) {
1409
+ documentOutgoingRelationships(
1410
+ sourceIdentifier: $sourceIdentifier
1411
+ relationshipType: $relationshipType
1412
+ view: $view
1413
+ paging: $paging
1414
+ ) {
1415
+ items {
1416
+ ...PHDocumentFields
1417
+ }
1418
+ totalCount
1419
+ hasNextPage
1420
+ hasPreviousPage
1421
+ cursor
1422
+ }
1423
+ }
1424
+ ${PhDocumentFieldsFragmentDoc}
1425
+ `;
1426
+ gql`
1427
+ query GetDocumentIncomingRelationships(
1428
+ $targetIdentifier: String!
1429
+ $relationshipType: String!
1430
+ $view: ViewFilterInput
1431
+ $paging: PagingInput
1432
+ ) {
1433
+ documentIncomingRelationships(
1434
+ targetIdentifier: $targetIdentifier
1435
+ relationshipType: $relationshipType
1436
+ view: $view
1437
+ paging: $paging
1438
+ ) {
1439
+ items {
1440
+ ...PHDocumentFields
1441
+ }
1442
+ totalCount
1443
+ hasNextPage
1444
+ hasPreviousPage
1445
+ cursor
1446
+ }
1447
+ }
1448
+ ${PhDocumentFieldsFragmentDoc}
1449
+ `;
1450
+ gql`
1451
+ query FindDocuments(
1452
+ $search: SearchFilterInput
1453
+ $view: ViewFilterInput
1454
+ $paging: PagingInput
1455
+ ) {
1456
+ findDocuments(search: $search, view: $view, paging: $paging) {
1457
+ items {
1458
+ ...PHDocumentFields
1459
+ }
1460
+ totalCount
1461
+ hasNextPage
1462
+ hasPreviousPage
1463
+ cursor
1464
+ }
1465
+ }
1466
+ ${PhDocumentFieldsFragmentDoc}
1467
+ `;
1468
+ const GetDocumentOperationsDocument = gql`
1469
+ query GetDocumentOperations(
1470
+ $filter: OperationsFilterInput!
1471
+ $paging: PagingInput
1472
+ ) {
1473
+ documentOperations(filter: $filter, paging: $paging) {
1474
+ items {
1475
+ index
1476
+ timestampUtcMs
1477
+ hash
1478
+ skip
1479
+ error
1480
+ deniedReason
1481
+ id
1482
+ action {
1483
+ id
1484
+ type
1485
+ timestampUtcMs
1486
+ input
1487
+ scope
1488
+ context {
1489
+ signer {
1490
+ user {
1491
+ address
1492
+ networkId
1493
+ chainId
1494
+ }
1495
+ app {
1496
+ name
1497
+ key
1498
+ }
1499
+ signatures
1500
+ }
1501
+ }
1502
+ }
1503
+ }
1504
+ totalCount
1505
+ hasNextPage
1506
+ hasPreviousPage
1507
+ cursor
1508
+ }
1509
+ }
1510
+ `;
1511
+ gql`
1512
+ query GetJobStatus($jobId: String!) {
1513
+ jobStatus(jobId: $jobId) {
1514
+ id
1515
+ status
1516
+ result
1517
+ error
1518
+ createdAt
1519
+ completedAt
1520
+ }
1521
+ }
1522
+ `;
1523
+ gql`
1524
+ query EvaluateActions(
1525
+ $documentIdentifier: String!
1526
+ $branch: String
1527
+ $candidates: [ActionCandidateInput!]!
1528
+ ) {
1529
+ evaluateActions(
1530
+ documentIdentifier: $documentIdentifier
1531
+ branch: $branch
1532
+ candidates: $candidates
1533
+ ) {
1534
+ evaluations {
1535
+ decision
1536
+ reason
1537
+ }
1538
+ allAllowed
1539
+ anyAllowed
1540
+ allDenied
1541
+ anyDenied
1542
+ }
1543
+ }
1544
+ `;
1545
+ gql`
1546
+ mutation CreateDocument($document: JSONObject!, $parentIdentifier: String) {
1547
+ createDocument(document: $document, parentIdentifier: $parentIdentifier) {
1548
+ ...PHDocumentFields
1549
+ }
1550
+ }
1551
+ ${PhDocumentFieldsFragmentDoc}
1552
+ `;
1553
+ gql`
1554
+ mutation CreateEmptyDocument(
1555
+ $documentType: String!
1556
+ $parentIdentifier: String
1557
+ ) {
1558
+ createEmptyDocument(
1559
+ documentType: $documentType
1560
+ parentIdentifier: $parentIdentifier
1561
+ ) {
1562
+ ...PHDocumentFields
1563
+ }
1564
+ }
1565
+ ${PhDocumentFieldsFragmentDoc}
1566
+ `;
1567
+ gql`
1568
+ mutation MutateDocument(
1569
+ $documentIdentifier: String!
1570
+ $actions: [ActionInput!]!
1571
+ $branch: String
1572
+ ) {
1573
+ mutateDocument: execute(
1574
+ documentIdentifier: $documentIdentifier
1575
+ actions: $actions
1576
+ branch: $branch
1577
+ ) {
1578
+ ...PHDocumentFields
1579
+ }
1580
+ }
1581
+ ${PhDocumentFieldsFragmentDoc}
1582
+ `;
1583
+ gql`
1584
+ mutation MutateDocumentAsync(
1585
+ $documentIdentifier: String!
1586
+ $actions: [ActionInput!]!
1587
+ $branch: String
1588
+ ) {
1589
+ mutateDocumentAsync: executeAsync(
1590
+ documentIdentifier: $documentIdentifier
1591
+ actions: $actions
1592
+ branch: $branch
1593
+ ) {
1594
+ id
1595
+ status
1596
+ result
1597
+ error
1598
+ createdAt
1599
+ completedAt
1600
+ }
1601
+ }
1602
+ `;
1603
+ gql`
1604
+ mutation RenameDocument(
1605
+ $documentIdentifier: String!
1606
+ $name: String!
1607
+ $branch: String
1608
+ ) {
1609
+ renameDocument(
1610
+ documentIdentifier: $documentIdentifier
1611
+ name: $name
1612
+ branch: $branch
1613
+ ) {
1614
+ ...PHDocumentFields
1615
+ }
1616
+ }
1617
+ ${PhDocumentFieldsFragmentDoc}
1618
+ `;
1619
+ gql`
1620
+ mutation SetPreferredEditor(
1621
+ $documentIdentifier: String!
1622
+ $preferredEditor: String
1623
+ $branch: String
1624
+ ) {
1625
+ setPreferredEditor(
1626
+ documentIdentifier: $documentIdentifier
1627
+ preferredEditor: $preferredEditor
1628
+ branch: $branch
1629
+ ) {
1630
+ ...PHDocumentFields
1631
+ }
1632
+ }
1633
+ ${PhDocumentFieldsFragmentDoc}
1634
+ `;
1635
+ gql`
1636
+ mutation AddRelationship(
1637
+ $sourceIdentifier: String!
1638
+ $targetIdentifier: String!
1639
+ $relationshipType: String!
1640
+ $branch: String
1641
+ ) {
1642
+ addRelationship(
1643
+ sourceIdentifier: $sourceIdentifier
1644
+ targetIdentifier: $targetIdentifier
1645
+ relationshipType: $relationshipType
1646
+ branch: $branch
1647
+ ) {
1648
+ ...PHDocumentFields
1649
+ }
1650
+ }
1651
+ ${PhDocumentFieldsFragmentDoc}
1652
+ `;
1653
+ gql`
1654
+ mutation RemoveRelationship(
1655
+ $sourceIdentifier: String!
1656
+ $targetIdentifier: String!
1657
+ $relationshipType: String!
1658
+ $branch: String
1659
+ ) {
1660
+ removeRelationship(
1661
+ sourceIdentifier: $sourceIdentifier
1662
+ targetIdentifier: $targetIdentifier
1663
+ relationshipType: $relationshipType
1664
+ branch: $branch
1665
+ ) {
1666
+ ...PHDocumentFields
1667
+ }
1668
+ }
1669
+ ${PhDocumentFieldsFragmentDoc}
1670
+ `;
1671
+ gql`
1672
+ mutation MoveRelationship(
1673
+ $sourceParentIdentifier: String!
1674
+ $targetParentIdentifier: String!
1675
+ $targetIdentifier: String!
1676
+ $relationshipType: String!
1677
+ $branch: String
1678
+ ) {
1679
+ moveRelationship(
1680
+ sourceParentIdentifier: $sourceParentIdentifier
1681
+ targetParentIdentifier: $targetParentIdentifier
1682
+ targetIdentifier: $targetIdentifier
1683
+ relationshipType: $relationshipType
1684
+ branch: $branch
1685
+ ) {
1686
+ source {
1687
+ ...PHDocumentFields
1688
+ }
1689
+ target {
1690
+ ...PHDocumentFields
1691
+ }
1692
+ }
1693
+ }
1694
+ ${PhDocumentFieldsFragmentDoc}
1695
+ `;
1696
+ gql`
1697
+ mutation DeleteDocument($identifier: String!, $propagate: PropagationMode) {
1698
+ deleteDocument(identifier: $identifier, propagate: $propagate)
1699
+ }
1700
+ `;
1701
+ gql`
1702
+ mutation DeleteDocuments(
1703
+ $identifiers: [String!]!
1704
+ $propagate: PropagationMode
1705
+ ) {
1706
+ deleteDocuments(identifiers: $identifiers, propagate: $propagate)
1707
+ }
1708
+ `;
1709
+ gql`
1710
+ subscription DocumentChanges(
1711
+ $search: SearchFilterInput
1712
+ $view: ViewFilterInput
1713
+ ) {
1714
+ documentChanges(search: $search, view: $view) {
1715
+ type
1716
+ documents {
1717
+ ...PHDocumentFields
1718
+ }
1719
+ context {
1720
+ parentId
1721
+ childId
1722
+ }
1723
+ }
1724
+ }
1725
+ ${PhDocumentFieldsFragmentDoc}
1726
+ `;
1727
+ gql`
1728
+ subscription JobChanges($jobId: String!) {
1729
+ jobChanges(jobId: $jobId) {
1730
+ jobId
1731
+ status
1732
+ result
1733
+ error
1734
+ }
1735
+ }
1736
+ `;
1737
+ gql`
1738
+ query PollSyncEnvelopes(
1739
+ $channelId: String!
1740
+ $outboxAck: Int!
1741
+ $outboxLatest: Int!
1742
+ ) {
1743
+ pollSyncEnvelopes(
1744
+ channelId: $channelId
1745
+ outboxAck: $outboxAck
1746
+ outboxLatest: $outboxLatest
1747
+ ) {
1748
+ envelopes {
1749
+ type
1750
+ channelMeta {
1751
+ id
1752
+ }
1753
+ operations {
1754
+ operation {
1755
+ index
1756
+ timestampUtcMs
1757
+ hash
1758
+ skip
1759
+ error
1760
+ deniedReason
1761
+ id
1762
+ action {
1763
+ id
1764
+ type
1765
+ timestampUtcMs
1766
+ input
1767
+ scope
1768
+ context {
1769
+ signer {
1770
+ user {
1771
+ address
1772
+ networkId
1773
+ chainId
1774
+ }
1775
+ app {
1776
+ name
1777
+ key
1778
+ }
1779
+ signatures
1780
+ }
1781
+ }
1782
+ }
1783
+ }
1784
+ context {
1785
+ documentId
1786
+ documentType
1787
+ scope
1788
+ branch
1789
+ }
1790
+ }
1791
+ cursor {
1792
+ remoteName
1793
+ cursorOrdinal
1794
+ lastSyncedAtUtcMs
1795
+ }
1796
+ key
1797
+ dependsOn
1798
+ }
1799
+ ackOrdinal
1800
+ deadLetters {
1801
+ documentId
1802
+ error
1803
+ errorType
1804
+ }
1805
+ hasMore
1806
+ }
1807
+ }
1808
+ `;
1809
+ gql`
1810
+ mutation TouchChannel($input: TouchChannelInput!) {
1811
+ touchChannel(input: $input) {
1812
+ success
1813
+ ackOrdinal
1814
+ }
1815
+ }
1816
+ `;
1817
+ gql`
1818
+ mutation PushSyncEnvelopes($envelopes: [SyncEnvelopeInput!]!) {
1819
+ pushSyncEnvelopes(envelopes: $envelopes)
1820
+ }
1821
+ `;
1822
+ /** Get the source string from a GraphQL document (string or DocumentNode). */
1823
+ function getDocumentSource(doc) {
1824
+ return typeof doc === "string" ? doc : doc.loc?.source.body ?? "";
1849
1825
  }
1850
- function isDocumentTypeSupported(documentType, supportedDocuments) {
1851
- if (!supportedDocuments?.length) return true;
1852
- return supportedDocuments.some((pattern) => {
1853
- if (pattern.endsWith("/*")) {
1854
- const prefix = pattern.slice(0, -2);
1855
- return documentType.startsWith(prefix + "/");
1856
- }
1857
- if (pattern.endsWith("*") && !pattern.endsWith("/*")) {
1858
- const prefix = pattern.slice(0, -1);
1859
- return documentType.startsWith(prefix);
1860
- }
1861
- return pattern === documentType;
1862
- });
1826
+ /**
1827
+ * Extract the inner selection set of a named field from a GraphQL document source.
1828
+ * Returns the `{ ... }` block including braces.
1829
+ */
1830
+ function extractSelectionSet(doc, fieldName, fallback) {
1831
+ const source = getDocumentSource(doc);
1832
+ return new RegExp(`${fieldName}\\([^)]*\\)\\s*(\\{[\\s\\S]*\\})\\s*\\}`).exec(source)?.[1] ?? fallback;
1863
1833
  }
1864
- function getUserPermissions() {
1865
- const user = window.ph?.renown?.user;
1866
- const allowList = window.ph?.allowList;
1867
- if (!allowList) return {
1868
- isAllowedToCreateDocuments: true,
1869
- isAllowedToEditDocuments: true
1870
- };
1834
+ /**
1835
+ * Extract the query body and any fragment definitions from a GraphQL document.
1836
+ * Returns { body, fragments } where body is the content inside the query `{ ... }`
1837
+ * and fragments are any trailing fragment definitions.
1838
+ */
1839
+ function extractQueryParts(doc, fallbackBody) {
1840
+ const source = getDocumentSource(doc);
1841
+ const queryMatch = /^[^{]*\{([\s\S]*?)\}\s*(fragment[\s\S]*)?$/.exec(source);
1871
1842
  return {
1872
- isAllowedToCreateDocuments: allowList.includes(user?.address ?? ""),
1873
- isAllowedToEditDocuments: allowList.includes(user?.address ?? "")
1843
+ body: queryMatch?.[1]?.trim() ?? fallbackBody,
1844
+ fragments: queryMatch?.[2]?.trim() ?? ""
1874
1845
  };
1875
1846
  }
1876
- const NON_DOMAIN_SCOPES = new Set(["auth", "document"]);
1877
- /** An unreadable drive cannot be shown to hold no duplicate, so reads throw. */
1878
- async function isDocumentInLocation(reactorClient, document, driveId, parentFolder) {
1879
- const drive = await reactorClient.get(driveId);
1880
- const nodeById = drive.state.global.nodes.find((node) => node.id === document.header.id);
1881
- if (nodeById && nodeById.parentFolder === (parentFolder ?? null)) return {
1882
- isDuplicate: true,
1883
- duplicateType: "id",
1884
- nodeId: nodeById.id
1885
- };
1886
- const nodeByNameAndType = drive.state.global.nodes.find((node) => isFileNode(node) && node.name === document.header.name && node.documentType === document.header.documentType && node.parentFolder === (parentFolder ?? null));
1887
- if (nodeByNameAndType) return {
1888
- isDuplicate: true,
1889
- duplicateType: "name",
1890
- nodeId: nodeByNameAndType.id
1891
- };
1892
- return { isDuplicate: false };
1847
+ extractSelectionSet(GetDocumentOperationsDocument, "documentOperations", "{ items { index } }");
1848
+ extractQueryParts(GetDocumentDocument, "document(identifier: $identifier) { document { id name documentType state revisionsList { scope revision } createdAtUtcIso lastModifiedAtUtcIso } childIds }");
1849
+ //#endregion
1850
+ //#region ../reactor-browser/dist/renown-BHxwP7xU.js
1851
+ const { useValue: useLoading, setValue: setLoading, addEventHandler: addLoadingEventHandler } = makePHEventFunctions("loading");
1852
+ const RenownInitialUserContext = createContext({ state: "unknown" });
1853
+ /** First-render auth as a three-state value; use this to skip a spinner when anonymous. */
1854
+ function useRenownInitialAuth() {
1855
+ return useContext(RenownInitialUserContext);
1893
1856
  }
1894
- function getDocumentTypeIcon(document) {
1895
- switch (document.header.documentType) {
1896
- case "powerhouse/document-model": return "document-model";
1897
- case "powerhouse/app": return "app";
1898
- case "powerhouse/document-editor": return "editor";
1899
- case "powerhouse/subgraph": return "subgraph";
1900
- case "powerhouse/package": return "package";
1901
- case "powerhouse/processor": {
1902
- const processorType = document.state.global?.type;
1903
- if (processorType === "analytics") return "analytics-processor";
1904
- if (processorType === "relational") return "relational-processor";
1905
- if (processorType === "codegen") return "codegen-processor";
1906
- return;
1907
- }
1908
- default: return;
1909
- }
1857
+ function useRenownInitialUser() {
1858
+ const initial = useRenownInitialAuth();
1859
+ return initial.state === "authenticated" ? initial.user : void 0;
1910
1860
  }
1911
- async function downloadFile(document, fileName) {
1912
- try {
1913
- const data = await createZip(document);
1914
- const blob = new Blob([new Uint8Array(data)], { type: "application/zip" });
1915
- const link = window.document.createElement("a");
1916
- link.style.display = "none";
1917
- link.href = URL.createObjectURL(blob);
1918
- link.download = fileName;
1919
- window.document.body.appendChild(link);
1920
- link.click();
1921
- window.document.body.removeChild(link);
1922
- } catch (e) {
1923
- logger.error(e instanceof Error ? e.message : String(e));
1924
- }
1861
+ const renownEventFunctions = makePHEventFunctions("renown");
1862
+ renownEventFunctions.addEventHandler;
1863
+ /** Returns the renown instance */
1864
+ const useRenown = renownEventFunctions.useValue;
1865
+ renownEventFunctions.setValue;
1866
+ function jsonEqual(a, b) {
1867
+ if (a === b) return true;
1868
+ if (typeof a !== "object" || typeof b !== "object" || !a || !b) return false;
1869
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
1870
+ const ra = a;
1871
+ const rb = b;
1872
+ const keys = Object.keys(ra).filter((k) => ra[k] !== void 0);
1873
+ if (keys.length !== Object.keys(rb).filter((k) => rb[k] !== void 0).length) return false;
1874
+ return keys.every((k) => jsonEqual(ra[k], rb[k]));
1925
1875
  }
1926
- async function getDocumentExtension(document) {
1927
- const documentType = document.header.documentType;
1928
- let rawExtension;
1929
- if (documentType === "powerhouse/document-model") rawExtension = document.state.global?.extension;
1930
- else {
1931
- const reactorClient = window.ph?.reactorClientModule?.client;
1932
- if (reactorClient) {
1933
- const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
1934
- rawExtension = documentModelModules.find((m) => m.documentModel.global.id === documentType)?.utils.fileExtension;
1935
- }
1936
- }
1937
- return (rawExtension ?? "").replace(/^\.+|\.+$/g, "");
1876
+ function sameUser(a, b) {
1877
+ return jsonEqual(a, b);
1938
1878
  }
1939
- /**
1940
- * Fetches all operations for a document using cursor-based pagination.
1941
- * The reactor client handles multi-scope cursors transparently via
1942
- * composite cursors, so all scopes are fetched in a single paginated stream.
1943
- */
1944
- async function fetchDocumentOperations(reactorClient, document, pageSize = 100) {
1945
- const scopes = Object.keys(document.state);
1946
- const operations = {};
1947
- for (const scope of scopes) operations[scope] = [];
1948
- let cursor = "";
1949
- do {
1950
- const page = await reactorClient.getOperations(document.header.id, { scopes }, void 0, {
1951
- cursor,
1952
- limit: pageSize
1953
- });
1954
- for (const op of page.results) {
1955
- const scope = op.action.scope ?? "global";
1956
- if (operations[scope]) operations[scope].push(op);
1957
- }
1958
- cursor = page.nextCursor ?? "";
1959
- } while (cursor);
1960
- return operations;
1879
+ function resolveInstanceUser(instance, seed) {
1880
+ const restored = instance.user;
1881
+ if (restored) return sameUser(seed, restored) ? seed : restored;
1882
+ return instance.status === "initial" ? void 0 : seed;
1883
+ }
1884
+ /** Returns the current user from the renown instance, subscribing to user events */
1885
+ function useUser() {
1886
+ const renown = useRenown();
1887
+ const initialUser = useRenownInitialUser();
1888
+ const instance = renown ? renown : void 0;
1889
+ const [tracked, setTracked] = useState(() => ({
1890
+ instance,
1891
+ user: instance ? resolveInstanceUser(instance, initialUser) : initialUser
1892
+ }));
1893
+ const current = tracked.instance === instance ? tracked : {
1894
+ instance,
1895
+ user: instance ? resolveInstanceUser(instance, tracked.user ?? initialUser) : tracked.user
1896
+ };
1897
+ useEffect(() => {
1898
+ if (current !== tracked) setTracked(current);
1899
+ }, [current, tracked]);
1900
+ useEffect(() => {
1901
+ if (!instance) return;
1902
+ return instance.on("user", (user) => setTracked((prev) => ({
1903
+ instance,
1904
+ user: sameUser(prev.user, user) ? prev.user : user
1905
+ })));
1906
+ }, [instance]);
1907
+ return instance ? current.user : initialUser ?? current.user;
1961
1908
  }
1962
- function extractInitialState(documentScopeOps) {
1963
- const upgradeOp = documentScopeOps.find((op) => op.action.type === "UPGRADE_DOCUMENT");
1964
- if (!upgradeOp) throw new Error("No UPGRADE_DOCUMENT operation found — document is invalid");
1965
- const input = upgradeOp.action.input;
1966
- const initialState = input.initialState ?? input.state;
1967
- if (!initialState) throw new Error("UPGRADE_DOCUMENT operation has no initialState — document is invalid");
1968
- return initialState;
1909
+ //#endregion
1910
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/lazyDataLastImpl-DtF3cihj.js
1911
+ function e$8(e, t, n) {
1912
+ let r = (n) => e(n, ...t);
1913
+ return n === void 0 ? r : Object.assign(r, {
1914
+ lazy: n,
1915
+ lazyArgs: t
1916
+ });
1969
1917
  }
1970
- function filterDomainOperations(operations) {
1971
- return Object.fromEntries(Object.entries(operations).filter(([scope]) => !NON_DOMAIN_SCOPES.has(scope)));
1918
+ //#endregion
1919
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/purry.js
1920
+ function t$5(t, n, r) {
1921
+ let i = t.length - n.length;
1922
+ if (i === 0) return t(...n);
1923
+ if (i === 1) return e$8(t, n, r);
1924
+ throw Error(`Wrong number of arguments`);
1972
1925
  }
1973
- function countOperations(operations) {
1974
- let total = 0;
1975
- for (const ops of Object.values(operations)) total += ops?.length ?? 0;
1976
- return total;
1926
+ //#endregion
1927
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/allPass.js
1928
+ function t$4(...t) {
1929
+ return t$5(n$4, t);
1977
1930
  }
1978
- /**
1979
- * Split an imported document's domain operations at its mid-history upgrade
1980
- * boundaries, so the caller can re-dispatch each upgrade between segments.
1981
- *
1982
- * The seed's CREATE_DOCUMENT and 0 -> N upgrade are replayed by the creation
1983
- * path and must not be repeated. A later upgrade must be: it is where the
1984
- * reducer version changes, and dropping it replays everything after it through
1985
- * the module the document was created with.
1986
- */
1987
- function splitAtUpgradeBoundaries(operations) {
1988
- const upgrades = (operations.document ?? []).filter((op) => op.action.type === "UPGRADE_DOCUMENT").filter((op) => op.action.input.fromVersion > 0).sort((a, b) => a.index - b.index);
1989
- const domain = filterDomainOperations(operations);
1990
- if (upgrades.length === 0) return [{ operations: domain }];
1991
- const segments = [];
1992
- const consumed = /* @__PURE__ */ new Map();
1993
- const take = (until) => {
1994
- const slice = {};
1995
- for (const [scope, ops] of Object.entries(domain)) {
1996
- if (!ops) continue;
1997
- const from = consumed.get(scope) ?? 0;
1998
- const stop = Math.max(from, until(scope, ops));
1999
- const chunk = ops.slice(from, stop);
2000
- if (chunk.length > 0) slice[scope] = chunk;
2001
- consumed.set(scope, stop);
2002
- }
2003
- return slice;
2004
- };
2005
- for (const upgrade of upgrades) {
2006
- const input = upgrade.action.input;
2007
- const slice = take((scope, ops) => boundary(upgrade, scope, ops));
2008
- segments.push({
2009
- operations: slice,
2010
- upgradeTo: input.toVersion
2011
- });
2012
- }
2013
- const tail = take((_scope, ops) => ops.length);
2014
- if (countOperations(tail) > 0) segments.push({ operations: tail });
2015
- return segments;
1931
+ const n$4 = (e, t) => t.every((t) => t(e));
1932
+ //#endregion
1933
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/conditional-CTEJD5TX.js
1934
+ function e$7(e, t, n) {
1935
+ return e(n[0]) ? (e) => t(e, ...n) : t(...n);
2016
1936
  }
2017
- /**
2018
- * How many of a scope's operations precede an upgrade. Must stay identical to
2019
- * the boundary computation in `replayDocumentVersioned` — snapshots compare
2020
- * against operation indices, not array positions, and the timestamp fallback
2021
- * excludes the upgrade's own instant.
2022
- */
2023
- function boundary(upgrade, scope, ops) {
2024
- const snapshot = upgrade.action.input.revision;
2025
- if (snapshot !== void 0) {
2026
- const revision = snapshot[scope] ?? 0;
2027
- let count = 0;
2028
- for (let i = 0; i < ops.length; i++) if (ops[i].index < revision) count = i + 1;
2029
- return count;
2030
- }
2031
- for (let i = 0; i < ops.length; i++) if (ops[i].timestampUtcMs >= upgrade.timestampUtcMs) return i;
2032
- return ops.length;
1937
+ function t$3(...t) {
1938
+ return e$7(r, n$3, t);
2033
1939
  }
2034
- async function exportFile(document, suggestedName) {
2035
- const reactorClient = window.ph?.reactorClient;
2036
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2037
- const operations = await fetchDocumentOperations(reactorClient, document);
2038
- const initialState = extractInitialState(operations["document"] ?? []);
2039
- const documentWithOps = {
2040
- ...document,
2041
- operations,
2042
- initialState
2043
- };
2044
- const extension = await getDocumentExtension(documentWithOps);
2045
- const baseName = suggestedName || documentWithOps.header.name || "Untitled";
2046
- const name = extension ? `${baseName}.${extension}.phd` : `${baseName}.phd`;
2047
- if (!window.showSaveFilePicker) return await downloadFile(documentWithOps, name);
2048
- try {
2049
- const fileHandle = await window.showSaveFilePicker({ suggestedName: name });
2050
- await baseSaveToFileHandle(documentWithOps, fileHandle);
2051
- return fileHandle;
2052
- } catch (e) {
2053
- if (!(e instanceof DOMException && e.name === "AbortError")) throw e;
1940
+ function n$3(e, ...t) {
1941
+ for (let n of t) {
1942
+ if (typeof n == `function`) return n(e);
1943
+ let [t, r] = n;
1944
+ if (t(e)) return r(e);
2054
1945
  }
1946
+ throw Error(`conditional: data failed for all cases`);
2055
1947
  }
2056
- /**
2057
- * Loads a document file and replays it with version-aware reducers from the registry.
2058
- * Falls back to single-version legacy replay when no upgrade manifest is registered for
2059
- * the document type.
2060
- */
2061
- async function loadFile(path) {
2062
- const baseDocument = await baseLoadFromInput(path, (state) => state, { checkHashes: true });
2063
- const reactorClient = window.ph?.reactorClientModule?.client;
2064
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2065
- const documentType = baseDocument.header.documentType;
2066
- const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
2067
- const modulesForType = documentModelModules.filter((module) => module.documentModel.global.id === documentType);
2068
- if (modulesForType.length === 0) throw new DocumentModelNotFoundError(documentType);
2069
- const reducers = {};
2070
- for (const module of modulesForType) reducers[module.version ?? 1] = module.reducer;
2071
- const registry = window.ph?.reactorClientModule?.reactorModule?.documentModelRegistry;
2072
- let upgradeManifest;
2073
- if (registry) try {
2074
- upgradeManifest = registry.getUpgradeManifest(documentType);
2075
- } catch {}
2076
- return baseLoadFromInputVersioned(path, {
2077
- reducers,
2078
- upgradeManifest
2079
- });
2080
- }
2081
- async function addDocument(driveId, name, documentType, parentFolder, document, id, preferredEditor, documentModelVersion) {
2082
- const { isAllowedToCreateDocuments } = getUserPermissions();
2083
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to create documents");
2084
- const reactorClient = window.ph?.reactorClientModule?.client;
2085
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2086
- let documentModelModule;
2087
- if (documentModelVersion !== void 0) {
2088
- const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
2089
- const module = documentModelModules.find((m) => m.documentModel.global.id === documentType && (m.version ?? 1) === documentModelVersion);
2090
- if (!module) throw new Error(`Document model not found for type: ${documentType} with version: ${documentModelVersion}`);
2091
- documentModelModule = module;
2092
- } else documentModelModule = await reactorClient.getDocumentModelModule(documentType);
2093
- const newDocument = document ?? documentModelModule.utils.createDocument();
2094
- if (!document) newDocument.state.document.version = documentModelModule.version ?? 1;
2095
- newDocument.header.name = name;
2096
- if (preferredEditor) newDocument.header.meta = {
2097
- ...newDocument.header.meta,
2098
- preferredEditor
2099
- };
2100
- let newDoc;
2101
- try {
2102
- newDoc = await reactorClient.drives.addFile(driveId, newDocument, parentFolder);
2103
- } catch (e) {
2104
- logger.error("Error adding document: @error", e);
2105
- throw new Error("There was an error adding document", { cause: e });
2106
- }
2107
- return {
2108
- id: newDoc.header.id,
2109
- name: newDoc.header.name,
2110
- documentType,
2111
- parentFolder: parentFolder ?? null,
2112
- kind: "file"
2113
- };
1948
+ function r(e) {
1949
+ if (!Array.isArray(e)) return !1;
1950
+ let [t, n, ...r] = e;
1951
+ return typeof t == `function` && t.length <= 1 && typeof n == `function` && n.length <= 1 && r.length === 0;
2114
1952
  }
2115
- /**
2116
- * How many ids an import will try before giving up. The check before the create
2117
- * catches an id that is already taken; this bound covers the window between the
2118
- * two, where a create can still lose to a claim made in the meantime.
2119
- */
2120
- const IMPORT_ID_ATTEMPTS = 3;
2121
- /** True when this error, or anything it wraps, is a taken document id. */
2122
- function isDocumentAlreadyExists(error) {
2123
- let current = error;
2124
- while (current instanceof Error) {
2125
- if (current.name === "DocumentAlreadyExistsError") return true;
2126
- current = current.cause;
2127
- }
2128
- return false;
1953
+ //#endregion
1954
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/constant.js
1955
+ function e$6(e) {
1956
+ return () => e;
2129
1957
  }
2130
- /**
2131
- * Creates the imported document under an id that is free, retrying on a
2132
- * collision.
2133
- *
2134
- * The check cannot stand on its own: it answers for the moment it ran, and the
2135
- * create that follows can still land on an id claimed in between. The store
2136
- * rejects that create as DocumentAlreadyExistsError, which is not retryable
2137
- * under the same id and is resolved by minting another one. A create that
2138
- * fails leaves the drive untouched, so a retry has nothing to clean up.
2139
- */
2140
- async function createImportedDocument(reactor, document, driveId, name, parentFolder) {
2141
- let documentId = await reactor.isDocumentIdTaken(document.header.id) ? generateId() : document.header.id;
2142
- for (let attempt = 1;; attempt++) {
2143
- const header = createPresignedHeader(documentId, document.header.documentType);
2144
- header.lastModifiedAtUtcIso = document.header.createdAtUtcIso;
2145
- header.meta = document.header.meta;
2146
- header.name = name || document.header.name;
2147
- const initialDocument = {
2148
- ...document,
2149
- header,
2150
- state: document.initialState,
2151
- operations: Object.keys(document.operations).reduce((acc, key) => {
2152
- acc[key] = [];
2153
- return acc;
2154
- }, {})
2155
- };
2156
- try {
2157
- const fileNode = await addDocument(driveId, name || document.header.name, document.header.documentType, parentFolder, initialDocument, documentId, document.header.meta?.preferredEditor);
2158
- if (!fileNode) throw new Error("There was an error adding file");
2159
- return {
2160
- documentId,
2161
- fileNode
2162
- };
2163
- } catch (error) {
2164
- if (!isDocumentAlreadyExists(error) || attempt === IMPORT_ID_ATTEMPTS) throw error;
2165
- logger.warn(`Document id ${documentId} was taken between the check and the create; importing under a new id`);
2166
- documentId = generateId();
2167
- }
2168
- }
1958
+ //#endregion
1959
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/hasAtLeast.js
1960
+ function t$2(...t) {
1961
+ return t$5(n$2, t);
2169
1962
  }
2170
- async function addFileWithProgress(file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict) {
2171
- logger.verbose(`addFileWithProgress(drive: ${driveId}, name: ${name}, folder: ${parentFolder})`);
2172
- const reactor = window.ph?.reactorClientModule?.client;
2173
- if (!reactor) {
2174
- onProgress?.({
2175
- stage: "failed",
2176
- progress: 100,
2177
- error: "ReactorClient not initialized"
2178
- });
2179
- throw new Error("ReactorClient not initialized");
2180
- }
2181
- const { isAllowedToCreateDocuments } = getUserPermissions();
2182
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to create files");
2183
- try {
2184
- onProgress?.({
2185
- stage: "loading",
2186
- progress: 0
2187
- });
2188
- let document;
2189
- try {
2190
- document = await loadFile(file);
2191
- } catch (loadError) {
2192
- if (UnsupportedDocumentModelVersionError.isError(loadError)) {
2193
- showPHModal({
2194
- type: "documentVersionUnsupported",
2195
- documentType: loadError.documentType,
2196
- requiredVersion: loadError.requiredVersion,
2197
- availableVersions: loadError.availableVersions
2198
- });
2199
- onProgress?.({
2200
- stage: "failed",
2201
- progress: 100,
2202
- error: loadError.message
2203
- });
2204
- return;
2205
- }
2206
- const discoveryService = window.ph?.packageDiscoveryService;
2207
- if (discoveryService && DocumentModelNotFoundError.isError(loadError)) {
2208
- retryAfterDiscovery(discoveryService, loadError.documentType, file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict).catch((retryError) => {
2209
- logger.error("Import retry after discovery failed: @error", retryError);
2210
- onProgress?.({
2211
- stage: "failed",
2212
- progress: 100,
2213
- error: retryError instanceof Error ? retryError.message : String(retryError)
2214
- });
2215
- });
2216
- return;
1963
+ const n$2 = (e, t) => e.length >= t;
1964
+ //#endregion
1965
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/funnel.js
1966
+ const e$5 = Symbol(`funnel/voidReducer`), t$1 = () => e$5;
1967
+ function n$1(n, { triggerAt: r = `end`, minQuietPeriodMs: i, maxBurstDurationMs: a, minGapMs: o, reducer: s = t$1 }) {
1968
+ let c, l, u, d, f = () => {
1969
+ let t = u;
1970
+ t !== void 0 && (u = void 0, t === e$5 ? n() : n(t), o !== void 0 && (l = setTimeout(p, o)));
1971
+ }, p = () => {
1972
+ clearTimeout(l), l = void 0, c === void 0 && f();
1973
+ }, m = () => {
1974
+ clearTimeout(c), c = void 0, d = void 0, l === void 0 && f();
1975
+ };
1976
+ return {
1977
+ call: (...e) => {
1978
+ let t = c === void 0 && l === void 0;
1979
+ if ((r !== `start` || t) && (u = s(u, ...e)), !(c === void 0 && !t)) {
1980
+ if (i !== void 0 || a !== void 0 || o === void 0) {
1981
+ clearTimeout(c);
1982
+ let e = Date.now();
1983
+ d ??= e;
1984
+ let t = a === void 0 ? i ?? 0 : Math.min(i ?? a, Math.max(0, a - (e - d)));
1985
+ c = setTimeout(m, t);
1986
+ }
1987
+ r !== `end` && t && f();
2217
1988
  }
2218
- throw loadError;
2219
- }
2220
- const duplicateCheck = await isDocumentInLocation(reactor, document, driveId, parentFolder);
2221
- if (duplicateCheck.isDuplicate && !resolveConflict) {
2222
- onProgress?.({
2223
- stage: "conflict",
2224
- progress: 0,
2225
- duplicateType: duplicateCheck.duplicateType
2226
- });
2227
- return;
2228
- }
2229
- const documentType = getDocumentTypeIcon(document);
2230
- if (documentType) onProgress?.({
2231
- stage: "loading",
2232
- progress: 10,
2233
- documentType
2234
- });
2235
- else onProgress?.({
2236
- stage: "loading",
2237
- progress: 10
2238
- });
2239
- if (!isDocumentTypeSupported(document.header.documentType, documentTypes)) {
2240
- onProgress?.({
2241
- stage: "unsupported-document-type",
2242
- progress: 100,
2243
- error: `Document type ${document.header.documentType} is not supported`
2244
- });
2245
- throw new UnsupportedDocumentTypeError(document.header.documentType);
2246
- }
2247
- await reactor.getDocumentModelModule(document.header.documentType);
2248
- onProgress?.({
2249
- stage: "initializing",
2250
- progress: 10
2251
- });
2252
- const created = await createImportedDocument(reactor, document, driveId, name, parentFolder);
2253
- const documentId = created.documentId;
2254
- const fileNode = created.fileNode;
2255
- onProgress?.({
2256
- stage: "initializing",
2257
- progress: 20
2258
- });
2259
- await reactor.get(documentId);
2260
- console.log("Document created, starting upload of operations");
2261
- const segments = splitAtUpgradeBoundaries(document.operations);
2262
- const totalOperations = segments.reduce((total, segment) => total + countOperations(segment.operations), 0);
2263
- let uploadedBefore = 0;
2264
- for (const segment of segments) {
2265
- await uploadOperations(documentId, segment.operations, queueOperations, { onProgress: (uploadProgress) => {
2266
- if (uploadProgress.uploadedOperations === void 0) return;
2267
- const uploaded = uploadedBefore + uploadProgress.uploadedOperations;
2268
- const uploadPercent = totalOperations > 0 ? uploaded / totalOperations : 0;
2269
- onProgress?.({
2270
- stage: "uploading",
2271
- progress: 20 + Math.round(uploadPercent * 80),
2272
- totalOperations,
2273
- uploadedOperations: uploaded
2274
- });
2275
- } });
2276
- uploadedBefore += countOperations(segment.operations);
2277
- if (segment.upgradeTo !== void 0) await reactor.upgradeDocument(documentId, segment.upgradeTo);
2278
- }
2279
- onProgress?.({
2280
- stage: "complete",
2281
- progress: 100,
2282
- fileNode
2283
- });
2284
- return fileNode;
2285
- } catch (error) {
2286
- if (!UnsupportedDocumentTypeError.isError(error)) {
2287
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2288
- onProgress?.({
2289
- stage: "failed",
2290
- progress: 100,
2291
- error: errorMessage
2292
- });
1989
+ },
1990
+ cancel: () => {
1991
+ clearTimeout(c), c = void 0, d = void 0, clearTimeout(l), l = void 0, u = void 0;
1992
+ },
1993
+ flush: () => {
1994
+ m(), p();
1995
+ },
1996
+ get isIdle() {
1997
+ return c === void 0 && l === void 0;
2293
1998
  }
2294
- throw error;
2295
- }
1999
+ };
2296
2000
  }
2297
- async function retryAfterDiscovery(discoveryService, documentType, file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict) {
2298
- if (!discoveryService) return;
2299
- try {
2300
- await discoveryService.load(documentType);
2301
- } catch {
2302
- onProgress?.({
2303
- stage: "unsupported-document-type",
2304
- progress: 100,
2305
- error: `Document type ${documentType} is not supported`
2306
- });
2307
- return;
2308
- }
2309
- await addFileWithProgress(file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict);
2001
+ //#endregion
2002
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isDefined.js
2003
+ function e$4(e) {
2004
+ return e !== void 0;
2310
2005
  }
2311
- async function addFolder$1(driveId, name, parentFolder) {
2312
- const { isAllowedToCreateDocuments } = getUserPermissions();
2313
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to create folders");
2314
- const reactorClient = window.ph?.reactorClient;
2315
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2316
- await reactorClient.get(driveId);
2317
- const folderId = generateId();
2318
- const node = (await reactorClient.execute(driveId, "main", [addFolder({
2319
- id: folderId,
2320
- name,
2321
- parentFolder
2322
- })])).state.global.nodes.find((node) => node.id === folderId);
2323
- if (!node || !isFolderNode(node)) throw new Error("There was an error adding folder");
2324
- return node;
2006
+ //#endregion
2007
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isNot.js
2008
+ function e$3(e) {
2009
+ return (t) => !e(t);
2325
2010
  }
2326
- async function renameNode(driveId, nodeId, name) {
2327
- const { isAllowedToCreateDocuments } = getUserPermissions();
2328
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to rename documents");
2329
- const reactorClient = window.ph?.reactorClient;
2330
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2331
- if ((await reactorClient.execute(nodeId, "main", [setName({ name })])).header.name !== name) throw new Error("There was an error renaming the node");
2332
- const node = (await reactorClient.execute(driveId, "main", [updateNode({
2333
- id: nodeId,
2334
- name
2335
- })])).state.global.nodes.find((n) => n.id === nodeId);
2336
- if (!node) throw new Error("There was an error renaming node in the drive");
2337
- return node;
2011
+ //#endregion
2012
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isStrictEqual.js
2013
+ function t(...t) {
2014
+ return t$5(n, t);
2015
+ }
2016
+ const n = (e, t) => e === t || Object.is(e, t);
2017
+ //#endregion
2018
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isString.js
2019
+ function e$2(e) {
2020
+ return typeof e == `string`;
2021
+ }
2022
+ //#endregion
2023
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/isTruthy.js
2024
+ function e$1(e) {
2025
+ return !!e;
2026
+ }
2027
+ //#endregion
2028
+ //#region ../../node_modules/.pnpm/remeda@2.33.7/node_modules/remeda/dist/once.js
2029
+ function e(e) {
2030
+ let t = !1, n;
2031
+ return () => (t ||= (n = e(), !0), n);
2032
+ }
2033
+ var CloseCode = /* @__PURE__ */ ((CloseCode2) => {
2034
+ CloseCode2[CloseCode2["InternalServerError"] = 4500] = "InternalServerError";
2035
+ CloseCode2[CloseCode2["InternalClientError"] = 4005] = "InternalClientError";
2036
+ CloseCode2[CloseCode2["BadRequest"] = 4400] = "BadRequest";
2037
+ CloseCode2[CloseCode2["BadResponse"] = 4004] = "BadResponse";
2038
+ CloseCode2[CloseCode2["Unauthorized"] = 4401] = "Unauthorized";
2039
+ CloseCode2[CloseCode2["Forbidden"] = 4403] = "Forbidden";
2040
+ CloseCode2[CloseCode2["SubprotocolNotAcceptable"] = 4406] = "SubprotocolNotAcceptable";
2041
+ CloseCode2[CloseCode2["ConnectionInitialisationTimeout"] = 4408] = "ConnectionInitialisationTimeout";
2042
+ CloseCode2[CloseCode2["ConnectionAcknowledgementTimeout"] = 4504] = "ConnectionAcknowledgementTimeout";
2043
+ CloseCode2[CloseCode2["SubscriberAlreadyExists"] = 4409] = "SubscriberAlreadyExists";
2044
+ CloseCode2[CloseCode2["TooManyInitialisationRequests"] = 4429] = "TooManyInitialisationRequests";
2045
+ return CloseCode2;
2046
+ })(CloseCode || {});
2047
+ var MessageType = /* @__PURE__ */ ((MessageType2) => {
2048
+ MessageType2["ConnectionInit"] = "connection_init";
2049
+ MessageType2["ConnectionAck"] = "connection_ack";
2050
+ MessageType2["Ping"] = "ping";
2051
+ MessageType2["Pong"] = "pong";
2052
+ MessageType2["Subscribe"] = "subscribe";
2053
+ MessageType2["Next"] = "next";
2054
+ MessageType2["Error"] = "error";
2055
+ MessageType2["Complete"] = "complete";
2056
+ return MessageType2;
2057
+ })(MessageType || {});
2058
+ Error;
2059
+ //#endregion
2060
+ //#region ../reactor-browser/dist/document-operations-I1cGIcPg.js
2061
+ const modalEventFunctions = makePHEventFunctions("modal");
2062
+ modalEventFunctions.useValue;
2063
+ /** Sets the current modal */
2064
+ const setPHModal = modalEventFunctions.setValue;
2065
+ modalEventFunctions.addEventHandler;
2066
+ /** Shows a modal */
2067
+ function showPHModal(modal) {
2068
+ setPHModal(modal);
2338
2069
  }
2339
- async function renameDriveNode(driveId, nodeId, name) {
2340
- const { isAllowedToCreateDocuments } = getUserPermissions();
2341
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to rename documents");
2342
- const reactorClient = window.ph?.reactorClient;
2343
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2344
- if ((await reactorClient.execute(nodeId, "main", [setName({ name })])).header.name !== name) throw new Error("There was an error renaming the node");
2345
- await reactorClient.execute(driveId, "main", [updateNode({
2346
- id: nodeId,
2347
- name
2348
- })]);
2349
- return (await reactorClient.get(driveId)).state.global.nodes.find((n) => n.id === nodeId);
2070
+ /** Shows the delete node modal */
2071
+ function showDeleteNodeModal(nodeOrId) {
2072
+ setPHModal({
2073
+ type: "deleteItem",
2074
+ id: typeof nodeOrId === "string" ? nodeOrId : nodeOrId.id
2075
+ });
2350
2076
  }
2351
- async function moveNodeById(args) {
2352
- const { driveId, srcId, targetId } = args;
2353
- if (!driveId || !srcId) return;
2354
- const { isAllowedToCreateDocuments } = getUserPermissions();
2355
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to move documents");
2356
- const reactorClient = window.ph?.reactorClient;
2357
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2358
- const targetParentFolder = t$3(targetId, [e$3(e$4), e$6(void 0)], [t(driveId), e$6(void 0)], e$6(targetId));
2359
- if (t(targetParentFolder, srcId)) return;
2360
- return await reactorClient.execute(driveId, "main", [moveNode({
2361
- srcFolder: srcId,
2362
- targetParentFolder
2363
- })]);
2077
+ function isDocumentTypeSupported(documentType, supportedDocuments) {
2078
+ if (!supportedDocuments?.length) return true;
2079
+ return supportedDocuments.some((pattern) => {
2080
+ if (pattern.endsWith("/*")) {
2081
+ const prefix = pattern.slice(0, -2);
2082
+ return documentType.startsWith(prefix + "/");
2083
+ }
2084
+ if (pattern.endsWith("*") && !pattern.endsWith("/*")) {
2085
+ const prefix = pattern.slice(0, -1);
2086
+ return documentType.startsWith(prefix);
2087
+ }
2088
+ return pattern === documentType;
2089
+ });
2364
2090
  }
2365
- async function moveNode$1(driveId, src, target) {
2366
- const { isAllowedToCreateDocuments } = getUserPermissions();
2367
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to move documents");
2368
- const reactorClient = window.ph?.reactorClient;
2369
- if (!reactorClient) throw new Error("ReactorClient not initialized");
2370
- return await reactorClient.execute(driveId, "main", [moveNode({
2371
- srcFolder: src.id,
2372
- targetParentFolder: target?.id
2373
- })]);
2091
+ function getUserPermissions() {
2092
+ const user = window.ph?.renown?.user;
2093
+ const allowList = window.ph?.allowList;
2094
+ if (!allowList) return {
2095
+ isAllowedToCreateDocuments: true,
2096
+ isAllowedToEditDocuments: true
2097
+ };
2098
+ return {
2099
+ isAllowedToCreateDocuments: allowList.includes(user?.address ?? ""),
2100
+ isAllowedToEditDocuments: allowList.includes(user?.address ?? "")
2101
+ };
2374
2102
  }
2375
- /**
2376
- * Duplicates a document under a new id using version-aware replay.
2377
- * Falls back gracefully when no upgrade manifest is registered for the document type.
2378
- */
2379
- async function _duplicateDocument(reactor, document, newId = generateId()) {
2380
- const documentType = document.header.documentType;
2381
- const { results: allModules } = await reactor.getDocumentModelModules();
2382
- const modulesForType = allModules.filter((m) => m.documentModel.global.id === documentType);
2383
- const reducers = {};
2384
- for (const m of modulesForType) reducers[m.version ?? 1] = m.reducer;
2385
- if (Object.keys(reducers).length === 0) throw new Error(`Document model module not found for type: ${documentType}`);
2386
- const registry = window.ph?.reactorClientModule?.reactorModule?.documentModelRegistry;
2387
- let upgradeManifest;
2388
- if (registry) try {
2389
- upgradeManifest = registry.getUpgradeManifest(documentType);
2390
- } catch {}
2391
- const config = {
2392
- reducers,
2393
- upgradeManifest
2103
+ const NON_DOMAIN_SCOPES = new Set(["auth", "document"]);
2104
+ /** An unreadable drive cannot be shown to hold no duplicate, so reads throw. */
2105
+ async function isDocumentInLocation(reactorClient, document, driveId, parentFolder) {
2106
+ const drive = await reactorClient.get(driveId);
2107
+ const nodeById = drive.state.global.nodes.find((node) => node.id === document.header.id);
2108
+ if (nodeById && nodeById.parentFolder === (parentFolder ?? null)) return {
2109
+ isDuplicate: true,
2110
+ duplicateType: "id",
2111
+ nodeId: nodeById.id
2394
2112
  };
2395
- const header = createPresignedHeader(newId, documentType);
2396
- const duplicated = replayDocumentVersioned(document.initialState, document.operations, config, header);
2397
- assertAuthPreservedOnDuplicate(document.header.id, document.state.auth, duplicated.state.auth);
2398
- return duplicated;
2113
+ const nodeByNameAndType = drive.state.global.nodes.find((node) => isFileNode(node) && node.name === document.header.name && node.documentType === document.header.documentType && node.parentFolder === (parentFolder ?? null));
2114
+ if (nodeByNameAndType) return {
2115
+ isDuplicate: true,
2116
+ duplicateType: "name",
2117
+ nodeId: nodeByNameAndType.id
2118
+ };
2119
+ return { isDuplicate: false };
2399
2120
  }
2400
- async function copyNode$1(driveId, src, target) {
2401
- const reactor = window.ph?.reactorClientModule?.client;
2402
- if (!reactor) return;
2403
- const { isAllowedToCreateDocuments } = getUserPermissions();
2404
- if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to copy documents");
2405
- const drive = await reactor.get(driveId);
2406
- const copyNodesInput = generateNodesCopy({
2407
- srcId: src.id,
2408
- targetParentFolder: target?.id,
2409
- targetName: src.name
2410
- }, () => generateId(), drive.state.global.nodes);
2411
- const resolvedNamesMap = /* @__PURE__ */ new Map();
2412
- for (const copyNodeInput of copyNodesInput) {
2413
- const node = drive.state.global.nodes.find((n) => n.id === copyNodeInput.srcId);
2414
- if (node) {
2415
- const resolvedName = handleTargetNameCollisions({
2416
- nodes: drive.state.global.nodes,
2417
- srcName: copyNodeInput.targetName || node.name,
2418
- srcKind: isFileNode(node) ? "file" : "folder",
2419
- targetParentFolder: copyNodeInput.targetParentFolder || null
2420
- });
2421
- resolvedNamesMap.set(copyNodeInput.targetId, resolvedName);
2121
+ function getDocumentTypeIcon(document) {
2122
+ switch (document.header.documentType) {
2123
+ case "powerhouse/document-model": return "document-model";
2124
+ case "powerhouse/app": return "app";
2125
+ case "powerhouse/document-editor": return "editor";
2126
+ case "powerhouse/subgraph": return "subgraph";
2127
+ case "powerhouse/package": return "package";
2128
+ case "powerhouse/processor": {
2129
+ const processorType = document.state.global?.type;
2130
+ if (processorType === "analytics") return "analytics-processor";
2131
+ if (processorType === "relational") return "relational-processor";
2132
+ if (processorType === "codegen") return "codegen-processor";
2133
+ return;
2422
2134
  }
2135
+ default: return;
2423
2136
  }
2424
- const fileNodesToCopy = copyNodesInput.filter((copyNodeInput) => {
2425
- const node = drive.state.global.nodes.find((node) => node.id === copyNodeInput.srcId);
2426
- return node !== void 0 && isFileNode(node);
2427
- });
2428
- for (const fileNodeToCopy of fileNodesToCopy) try {
2429
- const duplicatedDocument = await _duplicateDocument(reactor, await reactor.get(fileNodeToCopy.srcId), fileNodeToCopy.targetId);
2430
- const resolvedName = resolvedNamesMap.get(fileNodeToCopy.targetId);
2431
- if (resolvedName) duplicatedDocument.header.name = resolvedName;
2432
- await reactor.drives.addFile(driveId, duplicatedDocument, target?.id);
2137
+ }
2138
+ async function downloadFile(document, fileName) {
2139
+ try {
2140
+ const data = await createZip(document);
2141
+ const blob = new Blob([new Uint8Array(data)], { type: "application/zip" });
2142
+ const link = window.document.createElement("a");
2143
+ link.style.display = "none";
2144
+ link.href = URL.createObjectURL(blob);
2145
+ link.download = fileName;
2146
+ window.document.body.appendChild(link);
2147
+ link.click();
2148
+ window.document.body.removeChild(link);
2433
2149
  } catch (e) {
2434
- logger.error(`Error copying document ${fileNodeToCopy.srcId}: ${String(e)}`);
2150
+ logger.error(e instanceof Error ? e.message : String(e));
2435
2151
  }
2436
- return await queueActions(drive, copyNodesInput.map((copyNodeInput) => copyNode(copyNodeInput)));
2437
2152
  }
2438
- gql`
2439
- mutation MutateDocumentWithOperations(
2440
- $documentIdentifier: String!
2441
- $actions: [ActionInput!]!
2442
- $sinceRevision: Int
2443
- $scopes: [String!]
2444
- $branch: String
2445
- ) {
2446
- mutateDocument: execute(
2447
- documentIdentifier: $documentIdentifier
2448
- actions: $actions
2449
- branch: $branch
2450
- ) {
2451
- ...PHDocumentFields
2452
- operations(
2453
- filter: {
2454
- sinceRevision: $sinceRevision
2455
- scopes: $scopes
2456
- branch: $branch
2457
- }
2458
- ) {
2459
- items {
2460
- ...ReactorOperationFields
2461
- }
2462
- }
2463
- }
2464
- }
2465
- ${PhDocumentFieldsFragmentDoc}
2466
- ${gql`
2467
- fragment ReactorOperationFields on ReactorOperation {
2468
- index
2469
- timestampUtcMs
2470
- hash
2471
- skip
2472
- error
2473
- deniedReason
2474
- id
2475
- action {
2476
- id
2477
- type
2478
- timestampUtcMs
2479
- input
2480
- scope
2481
- context {
2482
- signer {
2483
- user {
2484
- address
2485
- networkId
2486
- chainId
2487
- }
2488
- app {
2489
- name
2490
- key
2491
- }
2492
- signatures
2493
- }
2494
- }
2495
- }
2496
- }
2497
- `}
2498
- `;
2499
- DocumentChangeType.Created, DOCUMENT_CHANGE_TYPE.Created, DocumentChangeType.Deleted, DOCUMENT_CHANGE_TYPE.Deleted, DocumentChangeType.Updated, DOCUMENT_CHANGE_TYPE.Updated, DocumentChangeType.ParentAdded, DOCUMENT_CHANGE_TYPE.ParentAdded, DocumentChangeType.ParentRemoved, DOCUMENT_CHANGE_TYPE.ParentRemoved, DocumentChangeType.ChildAdded, DOCUMENT_CHANGE_TYPE.ChildAdded, DocumentChangeType.ChildRemoved, DOCUMENT_CHANGE_TYPE.ChildRemoved;
2500
- PropagationMode.Cascade, PropagationMode.Orphan;
2501
- const isExternalControlsEnabledEventFunctions = makePHEventFunctions("isExternalControlsEnabled");
2502
- /** Sets whether external controls are enabled for a given editor. */
2503
- const setIsExternalControlsEnabled = isExternalControlsEnabledEventFunctions.setValue;
2504
- /** Gets whether external controls are enabled for a given editor. */
2505
- const useIsExternalControlsEnabled = isExternalControlsEnabledEventFunctions.useValue;
2506
- isExternalControlsEnabledEventFunctions.addEventHandler;
2507
- const isDragAndDropEnabledEventFunctions = makePHEventFunctions("isDragAndDropEnabled");
2508
- /** Sets whether drag and drop is enabled for a given app. */
2509
- const setIsDragAndDropEnabled = isDragAndDropEnabledEventFunctions.setValue;
2510
- /** Gets whether drag and drop is enabled for a given app. */
2511
- const useIsDragAndDropEnabled = isDragAndDropEnabledEventFunctions.useValue;
2512
- isDragAndDropEnabledEventFunctions.addEventHandler;
2513
- const allowedDocumentTypesEventFunctions = makePHEventFunctions("allowedDocumentTypes");
2514
- /** Sets the allowed document types for a given app. */
2515
- const setAllowedDocumentTypes = allowedDocumentTypesEventFunctions.setValue;
2516
- /** Defines the document types a drive supports.
2517
- *
2518
- * Defaults to all of the document types registered in the reactor.
2153
+ async function getDocumentExtension(document) {
2154
+ const documentType = document.header.documentType;
2155
+ let rawExtension;
2156
+ if (documentType === "powerhouse/document-model") rawExtension = document.state.global?.extension;
2157
+ else {
2158
+ const reactorClient = window.ph?.reactorClientModule?.client;
2159
+ if (reactorClient) {
2160
+ const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
2161
+ rawExtension = documentModelModules.find((m) => m.documentModel.global.id === documentType)?.utils.fileExtension;
2162
+ }
2163
+ }
2164
+ return (rawExtension ?? "").replace(/^\.+|\.+$/g, "");
2165
+ }
2166
+ /**
2167
+ * Fetches all operations for a document using cursor-based pagination.
2168
+ * The reactor client handles multi-scope cursors transparently via
2169
+ * composite cursors, so all scopes are fetched in a single paginated stream.
2519
2170
  */
2520
- function useAllowedDocumentTypes() {
2521
- return allowedDocumentTypesEventFunctions.useValue();
2171
+ async function fetchDocumentOperations(reactorClient, document, pageSize = 100) {
2172
+ const scopes = Object.keys(document.state);
2173
+ const operations = {};
2174
+ for (const scope of scopes) operations[scope] = [];
2175
+ let cursor = "";
2176
+ do {
2177
+ const page = await reactorClient.getOperations(document.header.id, { scopes }, void 0, {
2178
+ cursor,
2179
+ limit: pageSize
2180
+ });
2181
+ for (const op of page.results) {
2182
+ const scope = op.action.scope ?? "global";
2183
+ if (operations[scope]) operations[scope].push(op);
2184
+ }
2185
+ cursor = page.nextCursor ?? "";
2186
+ } while (cursor);
2187
+ return operations;
2522
2188
  }
2523
- allowedDocumentTypesEventFunctions.addEventHandler;
2524
- const phAppConfigSetters = {
2525
- allowedDocumentTypes: setAllowedDocumentTypes,
2526
- isDragAndDropEnabled: setIsDragAndDropEnabled
2527
- };
2528
- const phDocumentEditorConfigSetters = { isExternalControlsEnabled: setIsExternalControlsEnabled };
2529
- const phAppConfigHooks = {
2530
- allowedDocumentTypes: useAllowedDocumentTypes,
2531
- isDragAndDropEnabled: useIsDragAndDropEnabled
2532
- };
2533
- const phDocumentEditorConfigHooks = { isExternalControlsEnabled: useIsExternalControlsEnabled };
2534
- const { useValue: useRouterBasename, setValue: setRouterBasename, addEventHandler: addRouterBasenameEventHandler } = makePHEventFunctions("routerBasename");
2535
- const { useValue: useVersion, setValue: setVersion, addEventHandler: addVersionEventHandler } = makePHEventFunctions("version");
2536
- const { useValue: useRequiresHardRefresh, setValue: setRequiresHardRefresh, addEventHandler: addRequiresHardRefreshEventHandler } = makePHEventFunctions("requiresHardRefresh");
2537
- const { useValue: useWarnOutdatedApp, setValue: setWarnOutdatedApp, addEventHandler: addWarnOutdatedAppEventHandler } = makePHEventFunctions("warnOutdatedApp");
2538
- const { useValue: useStudioMode, setValue: setStudioMode, addEventHandler: addStudioModeEventHandler } = makePHEventFunctions("studioMode");
2539
- const { useValue: useBasePath, setValue: setBasePath, addEventHandler: addBasePathEventHandler } = makePHEventFunctions("basePath");
2540
- const { useValue: useVersionCheckInterval, setValue: setVersionCheckInterval, addEventHandler: addVersionCheckIntervalEventHandler } = makePHEventFunctions("versionCheckInterval");
2541
- const { useValue: useCliVersion, setValue: setCliVersion, addEventHandler: addCliVersionEventHandler } = makePHEventFunctions("cliVersion");
2542
- const { useValue: useFileUploadOperationsChunkSize, setValue: setFileUploadOperationsChunkSize, addEventHandler: addFileUploadOperationsChunkSizeEventHandler } = makePHEventFunctions("fileUploadOperationsChunkSize");
2543
- const { useValue: useIsDocumentModelSelectionSettingsEnabled, setValue: setIsDocumentModelSelectionSettingsEnabled, addEventHandler: addIsDocumentModelSelectionSettingsEnabledEventHandler } = makePHEventFunctions("isDocumentModelSelectionSettingsEnabled");
2544
- const { useValue: useGaTrackingId, setValue: setGaTrackingId, addEventHandler: addGaTrackingIdEventHandler } = makePHEventFunctions("gaTrackingId");
2545
- const { useValue: useDefaultDrivesUrl, setValue: setDefaultDrivesUrl, addEventHandler: addDefaultDrivesUrlEventHandler } = makePHEventFunctions("defaultDrivesUrl");
2546
- const { useValue: useDrivesPreserveStrategy, setValue: setDrivesPreserveStrategy, addEventHandler: addDrivesPreserveStrategyEventHandler } = makePHEventFunctions("drivesPreserveStrategy");
2547
- const { useValue: useIsLocalDrivesEnabled, setValue: setIsLocalDrivesEnabled, addEventHandler: addIsLocalDrivesEnabledEventHandler } = makePHEventFunctions("isLocalDrivesEnabled");
2548
- const { useValue: useIsAddDriveEnabled, setValue: setIsAddDriveEnabled, addEventHandler: addIsAddDriveEnabledEventHandler } = makePHEventFunctions("isAddDriveEnabled");
2549
- const { useValue: useIsPublicDrivesEnabled, setValue: setIsPublicDrivesEnabled, addEventHandler: addIsPublicDrivesEnabledEventHandler } = makePHEventFunctions("isPublicDrivesEnabled");
2550
- const { useValue: useIsAddPublicDrivesEnabled, setValue: setIsAddPublicDrivesEnabled, addEventHandler: addIsAddPublicDrivesEnabledEventHandler } = makePHEventFunctions("isAddPublicDrivesEnabled");
2551
- const { useValue: useIsDeletePublicDrivesEnabled, setValue: setIsDeletePublicDrivesEnabled, addEventHandler: addIsDeletePublicDrivesEnabledEventHandler } = makePHEventFunctions("isDeletePublicDrivesEnabled");
2552
- const { useValue: useIsCloudDrivesEnabled, setValue: setIsCloudDrivesEnabled, addEventHandler: addIsCloudDrivesEnabledEventHandler } = makePHEventFunctions("isCloudDrivesEnabled");
2553
- const { useValue: useIsAddCloudDrivesEnabled, setValue: setIsAddCloudDrivesEnabled, addEventHandler: addIsAddCloudDrivesEnabledEventHandler } = makePHEventFunctions("isAddCloudDrivesEnabled");
2554
- const { useValue: useIsDeleteCloudDrivesEnabled, setValue: setIsDeleteCloudDrivesEnabled, addEventHandler: addIsDeleteCloudDrivesEnabledEventHandler } = makePHEventFunctions("isDeleteCloudDrivesEnabled");
2555
- const { useValue: useLocalDrivesEnabled, setValue: setLocalDrivesEnabled, addEventHandler: addLocalDrivesEnabledEventHandler } = makePHEventFunctions("isLocalDrivesEnabled");
2556
- const { useValue: useIsAddLocalDrivesEnabled, setValue: setIsAddLocalDrivesEnabled, addEventHandler: addIsAddLocalDrivesEnabledEventHandler } = makePHEventFunctions("isAddLocalDrivesEnabled");
2557
- const { useValue: useIsDeleteLocalDrivesEnabled, setValue: setIsDeleteLocalDrivesEnabled, addEventHandler: addIsDeleteLocalDrivesEnabledEventHandler } = makePHEventFunctions("isDeleteLocalDrivesEnabled");
2558
- const { useValue: useIsEditorDebugModeEnabled, setValue: setIsEditorDebugModeEnabled, addEventHandler: addIsEditorDebugModeEnabledEventHandler } = makePHEventFunctions("isEditorDebugModeEnabled");
2559
- const { useValue: useIsEditorReadModeEnabled, setValue: setIsEditorReadModeEnabled, addEventHandler: addIsEditorReadModeEnabledEventHandler } = makePHEventFunctions("isEditorReadModeEnabled");
2560
- const { useValue: useIsAnalyticsDatabaseWorkerEnabled, setValue: setIsAnalyticsDatabaseWorkerEnabled, addEventHandler: addIsAnalyticsDatabaseWorkerEnabledEventHandler } = makePHEventFunctions("isAnalyticsDatabaseWorkerEnabled");
2561
- const { useValue: useIsDiffAnalyticsEnabled, setValue: setIsDiffAnalyticsEnabled, addEventHandler: addIsDiffAnalyticsEnabledEventHandler } = makePHEventFunctions("isDiffAnalyticsEnabled");
2562
- const { useValue: useIsDriveAnalyticsEnabled, setValue: setIsDriveAnalyticsEnabled, addEventHandler: addIsDriveAnalyticsEnabledEventHandler } = makePHEventFunctions("isDriveAnalyticsEnabled");
2563
- const { useValue: useRenownUrl, setValue: setRenownUrl, addEventHandler: addRenownUrlEventHandler } = makePHEventFunctions("renownUrl");
2564
- const { useValue: useRenownNetworkId, setValue: setRenownNetworkId, addEventHandler: addRenownNetworkIdEventHandler } = makePHEventFunctions("renownNetworkId");
2565
- const { useValue: useRenownChainId, setValue: setRenownChainId, addEventHandler: addRenownChainIdEventHandler } = makePHEventFunctions("renownChainId");
2566
- const { useValue: useSwitchboardUrl, setValue: setSwitchboardUrl, addEventHandler: addSwitchboardUrlEventHandler } = makePHEventFunctions("switchboardUrl");
2567
- const { useValue: useRenownAdapters, setValue: setRenownAdapters, addEventHandler: addRenownAdaptersEventHandler } = makePHEventFunctions("renownAdapters");
2568
- const { useValue: useSentryRelease, setValue: setSentryRelease, addEventHandler: addSentryReleaseEventHandler } = makePHEventFunctions("sentryRelease");
2569
- const { useValue: useSentryDsn, setValue: setSentryDsn, addEventHandler: addSentryDsnEventHandler } = makePHEventFunctions("sentryDsn");
2570
- const { useValue: useSentryEnv, setValue: setSentryEnv, addEventHandler: addSentryEnvEventHandler } = makePHEventFunctions("sentryEnv");
2571
- const { useValue: useIsSentryTracingEnabled, setValue: setIsSentryTracingEnabled, addEventHandler: addIsSentryTracingEnabledEventHandler } = makePHEventFunctions("isSentryTracingEnabled");
2572
- const { useValue: useIsExternalProcessorsEnabled, setValue: setIsExternalProcessorsEnabled, addEventHandler: addIsExternalProcessorsEnabledEventHandler } = makePHEventFunctions("isExternalProcessorsEnabled");
2573
- const { useValue: useIsExternalPackagesEnabled, setValue: setIsExternalPackagesEnabled, addEventHandler: addIsExternalPackagesEnabledEventHandler } = makePHEventFunctions("isExternalPackagesEnabled");
2574
- const enabledEditorsEventFunctions = makePHEventFunctions("enabledEditors");
2575
- /** Sets the enabled editors for Connect. */
2576
- const setEnabledEditors = enabledEditorsEventFunctions.setValue;
2577
- /** Gets the enabled editors for Connect. */
2578
- const useEnabledEditors = enabledEditorsEventFunctions.useValue;
2579
- enabledEditorsEventFunctions.addEventHandler;
2580
- const disabledEditorsEventFunctions = makePHEventFunctions("disabledEditors");
2581
- /** Sets the disabled editors for Connect. */
2582
- const setDisabledEditors = disabledEditorsEventFunctions.setValue;
2583
- /** Gets the disabled editors for Connect. */
2584
- const useDisabledEditors = disabledEditorsEventFunctions.useValue;
2585
- disabledEditorsEventFunctions.addEventHandler;
2586
- const isRelationalProcessorsEnabled = makePHEventFunctions("isRelationalProcessorsEnabled");
2587
- /** Sets the isRelationalProcessorsEnabled for Connect. */
2588
- const setIsRelationalProcessorsEnabled = isRelationalProcessorsEnabled.setValue;
2589
- /** Gets the isRelationalProcessorsEnabled for Connect. */
2590
- const useIsRelationalProcessorsEnabled = isRelationalProcessorsEnabled.useValue;
2591
- isRelationalProcessorsEnabled.addEventHandler;
2592
- const isExternalRelationalProcessorsEnabled = makePHEventFunctions("isExternalRelationalProcessorsEnabled");
2593
- /** Sets the isExternalRelationalProcessorsEnabled for Connect. */
2594
- const setIsExternalRelationalProcessorsEnabled = isExternalRelationalProcessorsEnabled.setValue;
2595
- /** Gets the isExternalRelationalProcessorsEnabled for Connect. */
2596
- const useIsExternalRelationalProcessorsEnabled = isExternalRelationalProcessorsEnabled.useValue;
2597
- isExternalRelationalProcessorsEnabled.addEventHandler;
2598
- const isAnalyticsEnabledEventFunctions = makePHEventFunctions("isAnalyticsEnabled");
2599
- /** Sets the isAnalyticsEnabled for Connect. */
2600
- const setIsAnalyticsEnabled = isAnalyticsEnabledEventFunctions.setValue;
2601
- /** Gets the isAnalyticsEnabled for Connect. */
2602
- const useIsAnalyticsEnabled = isAnalyticsEnabledEventFunctions.useValue;
2603
- isAnalyticsEnabledEventFunctions.addEventHandler;
2604
- const isAnalyticsExternalProcessorsEnabled = makePHEventFunctions("isAnalyticsExternalProcessorsEnabled");
2605
- /** Sets the isAnalyticsExternalProcessorsEnabled for Connect. */
2606
- const setIsAnalyticsExternalProcessorsEnabled = isAnalyticsExternalProcessorsEnabled.setValue;
2607
- /** Gets the isAnalyticsExternalProcessorsEnabled for Connect. */
2608
- const useIsAnalyticsExternalProcessorsEnabled = isAnalyticsExternalProcessorsEnabled.useValue;
2609
- isAnalyticsExternalProcessorsEnabled.addEventHandler;
2610
- const analyticsDatabaseNameEventFunctions = makePHEventFunctions("analyticsDatabaseName");
2611
- /** Sets the analytics database name for Connect. */
2612
- const setAnalyticsDatabaseName = analyticsDatabaseNameEventFunctions.setValue;
2613
- /** Gets the analytics database name for Connect. */
2614
- const useAnalyticsDatabaseName = analyticsDatabaseNameEventFunctions.useValue;
2615
- analyticsDatabaseNameEventFunctions.addEventHandler;
2616
- const logLevelEventFunctions = makePHEventFunctions("logLevel");
2617
- /** Sets the log level for Connect. */
2618
- const setLogLevel = logLevelEventFunctions.setValue;
2619
- /** Gets the log level for Connect. */
2620
- const useLogLevel = logLevelEventFunctions.useValue;
2621
- logLevelEventFunctions.addEventHandler;
2622
- const allowListEventFunctions = makePHEventFunctions("allowList");
2623
- /** Sets the allow list for Connect. */
2624
- const setAllowList = allowListEventFunctions.setValue;
2625
- /** Gets the allow list for Connect. */
2626
- const useAllowList = allowListEventFunctions.useValue;
2627
- allowListEventFunctions.addEventHandler;
2628
- const nonUserConfigSetters = {
2629
- routerBasename: setRouterBasename,
2630
- version: setVersion,
2631
- requiresHardRefresh: setRequiresHardRefresh,
2632
- warnOutdatedApp: setWarnOutdatedApp,
2633
- studioMode: setStudioMode,
2634
- basePath: setBasePath,
2635
- versionCheckInterval: setVersionCheckInterval,
2636
- cliVersion: setCliVersion,
2637
- fileUploadOperationsChunkSize: setFileUploadOperationsChunkSize,
2638
- isDocumentModelSelectionSettingsEnabled: setIsDocumentModelSelectionSettingsEnabled,
2639
- gaTrackingId: setGaTrackingId,
2640
- defaultDrivesUrl: setDefaultDrivesUrl,
2641
- drivesPreserveStrategy: setDrivesPreserveStrategy,
2642
- isLocalDrivesEnabled: setIsLocalDrivesEnabled,
2643
- isAddDriveEnabled: setIsAddDriveEnabled,
2644
- isPublicDrivesEnabled: setIsPublicDrivesEnabled,
2645
- isAddPublicDrivesEnabled: setIsAddPublicDrivesEnabled,
2646
- isDeletePublicDrivesEnabled: setIsDeletePublicDrivesEnabled,
2647
- isCloudDrivesEnabled: setIsCloudDrivesEnabled,
2648
- isAddCloudDrivesEnabled: setIsAddCloudDrivesEnabled,
2649
- isDeleteCloudDrivesEnabled: setIsDeleteCloudDrivesEnabled,
2650
- isAddLocalDrivesEnabled: setIsAddLocalDrivesEnabled,
2651
- isDeleteLocalDrivesEnabled: setIsDeleteLocalDrivesEnabled,
2652
- isEditorDebugModeEnabled: setIsEditorDebugModeEnabled,
2653
- isEditorReadModeEnabled: setIsEditorReadModeEnabled,
2654
- isRelationalProcessorsEnabled: setIsRelationalProcessorsEnabled,
2655
- isExternalRelationalProcessorsEnabled: setIsExternalRelationalProcessorsEnabled,
2656
- isAnalyticsEnabled: setIsAnalyticsEnabled,
2657
- analyticsDatabaseName: setAnalyticsDatabaseName,
2658
- isAnalyticsExternalProcessorsEnabled: setIsAnalyticsExternalProcessorsEnabled,
2659
- isAnalyticsDatabaseWorkerEnabled: setIsAnalyticsDatabaseWorkerEnabled,
2660
- isDiffAnalyticsEnabled: setIsDiffAnalyticsEnabled,
2661
- isDriveAnalyticsEnabled: setIsDriveAnalyticsEnabled,
2662
- renownUrl: setRenownUrl,
2663
- renownNetworkId: setRenownNetworkId,
2664
- renownChainId: setRenownChainId,
2665
- switchboardUrl: setSwitchboardUrl,
2666
- renownAdapters: setRenownAdapters,
2667
- sentryRelease: setSentryRelease,
2668
- sentryDsn: setSentryDsn,
2669
- sentryEnv: setSentryEnv,
2670
- isSentryTracingEnabled: setIsSentryTracingEnabled,
2671
- isExternalProcessorsEnabled: setIsExternalProcessorsEnabled,
2672
- isExternalPackagesEnabled: setIsExternalPackagesEnabled,
2673
- allowList: setAllowList,
2674
- logLevel: setLogLevel,
2675
- disabledEditors: setDisabledEditors,
2676
- enabledEditors: setEnabledEditors
2677
- };
2678
- const phGlobalConfigSetters = {
2679
- ...phAppConfigSetters,
2680
- ...phDocumentEditorConfigSetters,
2681
- ...nonUserConfigSetters
2682
- };
2683
- const nonUserConfigHooks = {
2684
- routerBasename: useRouterBasename,
2685
- version: useVersion,
2686
- requiresHardRefresh: useRequiresHardRefresh,
2687
- warnOutdatedApp: useWarnOutdatedApp,
2688
- studioMode: useStudioMode,
2689
- basePath: useBasePath,
2690
- versionCheckInterval: useVersionCheckInterval,
2691
- cliVersion: useCliVersion,
2692
- fileUploadOperationsChunkSize: useFileUploadOperationsChunkSize,
2693
- isDocumentModelSelectionSettingsEnabled: useIsDocumentModelSelectionSettingsEnabled,
2694
- gaTrackingId: useGaTrackingId,
2695
- defaultDrivesUrl: useDefaultDrivesUrl,
2696
- drivesPreserveStrategy: useDrivesPreserveStrategy,
2697
- isAddDriveEnabled: useIsAddDriveEnabled,
2698
- isPublicDrivesEnabled: useIsPublicDrivesEnabled,
2699
- isAddPublicDrivesEnabled: useIsAddPublicDrivesEnabled,
2700
- isDeletePublicDrivesEnabled: useIsDeletePublicDrivesEnabled,
2701
- isCloudDrivesEnabled: useIsCloudDrivesEnabled,
2702
- isAddCloudDrivesEnabled: useIsAddCloudDrivesEnabled,
2703
- isDeleteCloudDrivesEnabled: useIsDeleteCloudDrivesEnabled,
2704
- isLocalDrivesEnabled: useIsLocalDrivesEnabled,
2705
- isAddLocalDrivesEnabled: useIsAddLocalDrivesEnabled,
2706
- isDeleteLocalDrivesEnabled: useIsDeleteLocalDrivesEnabled,
2707
- isEditorDebugModeEnabled: useIsEditorDebugModeEnabled,
2708
- isEditorReadModeEnabled: useIsEditorReadModeEnabled,
2709
- isAnalyticsDatabaseWorkerEnabled: useIsAnalyticsDatabaseWorkerEnabled,
2710
- isDiffAnalyticsEnabled: useIsDiffAnalyticsEnabled,
2711
- isDriveAnalyticsEnabled: useIsDriveAnalyticsEnabled,
2712
- renownUrl: useRenownUrl,
2713
- renownNetworkId: useRenownNetworkId,
2714
- renownChainId: useRenownChainId,
2715
- switchboardUrl: useSwitchboardUrl,
2716
- renownAdapters: useRenownAdapters,
2717
- sentryRelease: useSentryRelease,
2718
- sentryDsn: useSentryDsn,
2719
- sentryEnv: useSentryEnv,
2720
- isSentryTracingEnabled: useIsSentryTracingEnabled,
2721
- isExternalProcessorsEnabled: useIsExternalProcessorsEnabled,
2722
- isExternalPackagesEnabled: useIsExternalPackagesEnabled,
2723
- allowList: useAllowList,
2724
- isAnalyticsEnabled: useIsAnalyticsEnabled,
2725
- isAnalyticsExternalProcessorsEnabled: useIsAnalyticsExternalProcessorsEnabled,
2726
- isRelationalProcessorsEnabled: useIsRelationalProcessorsEnabled,
2727
- isExternalRelationalProcessorsEnabled: useIsExternalRelationalProcessorsEnabled,
2728
- analyticsDatabaseName: useAnalyticsDatabaseName,
2729
- logLevel: useLogLevel,
2730
- disabledEditors: useDisabledEditors,
2731
- enabledEditors: useEnabledEditors
2732
- };
2733
- ({
2734
- ...phAppConfigHooks,
2735
- ...phDocumentEditorConfigHooks,
2736
- ...nonUserConfigHooks
2737
- });
2738
- const attachmentServiceEventFunctions = makePHEventFunctions("attachmentService");
2739
- attachmentServiceEventFunctions.useValue;
2740
- attachmentServiceEventFunctions.setValue;
2741
- attachmentServiceEventFunctions.addEventHandler;
2742
- const featuresEventFunctions = makePHEventFunctions("features");
2743
- featuresEventFunctions.useValue;
2744
- featuresEventFunctions.setValue;
2745
- featuresEventFunctions.addEventHandler;
2746
- function resolveUrlPathname(path) {
2747
- return new URL(path.replace(/^\/+/, ""), window.location.origin + (window.ph?.basePath ?? "/")).pathname;
2189
+ function extractInitialState(documentScopeOps) {
2190
+ const upgradeOp = documentScopeOps.find((op) => op.action.type === "UPGRADE_DOCUMENT");
2191
+ if (!upgradeOp) throw new Error("No UPGRADE_DOCUMENT operation found — document is invalid");
2192
+ const input = upgradeOp.action.input;
2193
+ const initialState = input.initialState ?? input.state;
2194
+ if (!initialState) throw new Error("UPGRADE_DOCUMENT operation has no initialState — document is invalid");
2195
+ return initialState;
2196
+ }
2197
+ function filterDomainOperations(operations) {
2198
+ return Object.fromEntries(Object.entries(operations).filter(([scope]) => !NON_DOMAIN_SCOPES.has(scope)));
2199
+ }
2200
+ function countOperations(operations) {
2201
+ let total = 0;
2202
+ for (const ops of Object.values(operations)) total += ops?.length ?? 0;
2203
+ return total;
2204
+ }
2205
+ /**
2206
+ * Split an imported document's domain operations at its mid-history upgrade
2207
+ * boundaries, so the caller can re-dispatch each upgrade between segments.
2208
+ *
2209
+ * The seed's CREATE_DOCUMENT and 0 -> N upgrade are replayed by the creation
2210
+ * path and must not be repeated. A later upgrade must be: it is where the
2211
+ * reducer version changes, and dropping it replays everything after it through
2212
+ * the module the document was created with.
2213
+ */
2214
+ function splitAtUpgradeBoundaries(operations) {
2215
+ const upgrades = (operations.document ?? []).filter((op) => op.action.type === "UPGRADE_DOCUMENT").filter((op) => op.action.input.fromVersion > 0).sort((a, b) => a.index - b.index);
2216
+ const domain = filterDomainOperations(operations);
2217
+ if (upgrades.length === 0) return [{ operations: domain }];
2218
+ const segments = [];
2219
+ const consumed = /* @__PURE__ */ new Map();
2220
+ const take = (until) => {
2221
+ const slice = {};
2222
+ for (const [scope, ops] of Object.entries(domain)) {
2223
+ if (!ops) continue;
2224
+ const from = consumed.get(scope) ?? 0;
2225
+ const stop = Math.max(from, until(scope, ops));
2226
+ const chunk = ops.slice(from, stop);
2227
+ if (chunk.length > 0) slice[scope] = chunk;
2228
+ consumed.set(scope, stop);
2229
+ }
2230
+ return slice;
2231
+ };
2232
+ for (const upgrade of upgrades) {
2233
+ const input = upgrade.action.input;
2234
+ const slice = take((scope, ops) => boundary(upgrade, scope, ops));
2235
+ segments.push({
2236
+ operations: slice,
2237
+ upgradeTo: input.toVersion
2238
+ });
2239
+ }
2240
+ const tail = take((_scope, ops) => ops.length);
2241
+ if (countOperations(tail) > 0) segments.push({ operations: tail });
2242
+ return segments;
2243
+ }
2244
+ /**
2245
+ * How many of a scope's operations precede an upgrade. Must stay identical to
2246
+ * the boundary computation in `replayDocumentVersioned` — snapshots compare
2247
+ * against operation indices, not array positions, and the timestamp fallback
2248
+ * excludes the upgrade's own instant.
2249
+ */
2250
+ function boundary(upgrade, scope, ops) {
2251
+ const snapshot = upgrade.action.input.revision;
2252
+ if (snapshot !== void 0) {
2253
+ const revision = snapshot[scope] ?? 0;
2254
+ let count = 0;
2255
+ for (let i = 0; i < ops.length; i++) if (ops[i].index < revision) count = i + 1;
2256
+ return count;
2257
+ }
2258
+ for (let i = 0; i < ops.length; i++) if (ops[i].timestampUtcMs >= upgrade.timestampUtcMs) return i;
2259
+ return ops.length;
2260
+ }
2261
+ async function exportFile(document, suggestedName) {
2262
+ const reactorClient = window.ph?.reactorClient;
2263
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2264
+ const operations = await fetchDocumentOperations(reactorClient, document);
2265
+ const initialState = extractInitialState(operations["document"] ?? []);
2266
+ const documentWithOps = {
2267
+ ...document,
2268
+ operations,
2269
+ initialState
2270
+ };
2271
+ const extension = await getDocumentExtension(documentWithOps);
2272
+ const baseName = suggestedName || documentWithOps.header.name || "Untitled";
2273
+ const name = extension ? `${baseName}.${extension}.phd` : `${baseName}.phd`;
2274
+ if (!window.showSaveFilePicker) return await downloadFile(documentWithOps, name);
2275
+ try {
2276
+ const fileHandle = await window.showSaveFilePicker({ suggestedName: name });
2277
+ await baseSaveToFileHandle(documentWithOps, fileHandle);
2278
+ return fileHandle;
2279
+ } catch (e) {
2280
+ if (!(e instanceof DOMException && e.name === "AbortError")) throw e;
2281
+ }
2282
+ }
2283
+ /**
2284
+ * Loads a document file and replays it with version-aware reducers from the registry.
2285
+ * Falls back to single-version legacy replay when no upgrade manifest is registered for
2286
+ * the document type.
2287
+ */
2288
+ async function loadFile(path) {
2289
+ const baseDocument = await baseLoadFromInput(path, (state) => state, { checkHashes: true });
2290
+ const reactorClient = window.ph?.reactorClientModule?.client;
2291
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2292
+ const documentType = baseDocument.header.documentType;
2293
+ const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
2294
+ const modulesForType = documentModelModules.filter((module) => module.documentModel.global.id === documentType);
2295
+ if (modulesForType.length === 0) throw new DocumentModelNotFoundError(documentType);
2296
+ const reducers = {};
2297
+ for (const module of modulesForType) reducers[module.version ?? 1] = module.reducer;
2298
+ const registry = window.ph?.reactorClientModule?.reactorModule?.documentModelRegistry;
2299
+ let upgradeManifest;
2300
+ if (registry) try {
2301
+ upgradeManifest = registry.getUpgradeManifest(documentType);
2302
+ } catch {}
2303
+ return baseLoadFromInputVersioned(path, {
2304
+ reducers,
2305
+ upgradeManifest
2306
+ });
2307
+ }
2308
+ async function addDocument(driveId, name, documentType, parentFolder, document, id, preferredEditor, documentModelVersion) {
2309
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2310
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to create documents");
2311
+ const reactorClient = window.ph?.reactorClientModule?.client;
2312
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2313
+ let documentModelModule;
2314
+ if (documentModelVersion !== void 0) {
2315
+ const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
2316
+ const module = documentModelModules.find((m) => m.documentModel.global.id === documentType && (m.version ?? 1) === documentModelVersion);
2317
+ if (!module) throw new Error(`Document model not found for type: ${documentType} with version: ${documentModelVersion}`);
2318
+ documentModelModule = module;
2319
+ } else documentModelModule = await reactorClient.getDocumentModelModule(documentType);
2320
+ const newDocument = document ?? documentModelModule.utils.createDocument();
2321
+ if (!document) newDocument.state.document.version = documentModelModule.version ?? 1;
2322
+ newDocument.header.name = name;
2323
+ if (preferredEditor) newDocument.header.meta = {
2324
+ ...newDocument.header.meta,
2325
+ preferredEditor
2326
+ };
2327
+ let newDoc;
2328
+ try {
2329
+ newDoc = await reactorClient.drives.addFile(driveId, newDocument, parentFolder);
2330
+ } catch (e) {
2331
+ logger.error("Error adding document: @error", e);
2332
+ throw new Error("There was an error adding document", { cause: e });
2333
+ }
2334
+ return {
2335
+ id: newDoc.header.id,
2336
+ name: newDoc.header.name,
2337
+ documentType,
2338
+ parentFolder: parentFolder ?? null,
2339
+ kind: "file"
2340
+ };
2341
+ }
2342
+ /**
2343
+ * How many ids an import will try before giving up. The check before the create
2344
+ * catches an id that is already taken; this bound covers the window between the
2345
+ * two, where a create can still lose to a claim made in the meantime.
2346
+ */
2347
+ const IMPORT_ID_ATTEMPTS = 3;
2348
+ /** True when this error, or anything it wraps, is a taken document id. */
2349
+ function isDocumentAlreadyExists(error) {
2350
+ let current = error;
2351
+ while (current instanceof Error) {
2352
+ if (current.name === "DocumentAlreadyExistsError") return true;
2353
+ current = current.cause;
2354
+ }
2355
+ return false;
2356
+ }
2357
+ /**
2358
+ * Creates the imported document under an id that is free, retrying on a
2359
+ * collision.
2360
+ *
2361
+ * The check cannot stand on its own: it answers for the moment it ran, and the
2362
+ * create that follows can still land on an id claimed in between. The store
2363
+ * rejects that create as DocumentAlreadyExistsError, which is not retryable
2364
+ * under the same id and is resolved by minting another one. A create that
2365
+ * fails leaves the drive untouched, so a retry has nothing to clean up.
2366
+ */
2367
+ async function createImportedDocument(reactor, document, driveId, name, parentFolder) {
2368
+ let documentId = await reactor.isDocumentIdTaken(document.header.id) ? generateId() : document.header.id;
2369
+ for (let attempt = 1;; attempt++) {
2370
+ const header = createPresignedHeader(documentId, document.header.documentType);
2371
+ header.lastModifiedAtUtcIso = document.header.createdAtUtcIso;
2372
+ header.meta = document.header.meta;
2373
+ header.name = name || document.header.name;
2374
+ const initialDocument = {
2375
+ ...document,
2376
+ header,
2377
+ state: document.initialState,
2378
+ operations: Object.keys(document.operations).reduce((acc, key) => {
2379
+ acc[key] = [];
2380
+ return acc;
2381
+ }, {})
2382
+ };
2383
+ try {
2384
+ const fileNode = await addDocument(driveId, name || document.header.name, document.header.documentType, parentFolder, initialDocument, documentId, document.header.meta?.preferredEditor);
2385
+ if (!fileNode) throw new Error("There was an error adding file");
2386
+ return {
2387
+ documentId,
2388
+ fileNode
2389
+ };
2390
+ } catch (error) {
2391
+ if (!isDocumentAlreadyExists(error) || attempt === IMPORT_ID_ATTEMPTS) throw error;
2392
+ logger.warn(`Document id ${documentId} was taken between the check and the create; importing under a new id`);
2393
+ documentId = generateId();
2394
+ }
2395
+ }
2396
+ }
2397
+ async function addFileWithProgress(file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict) {
2398
+ logger.verbose(`addFileWithProgress(drive: ${driveId}, name: ${name}, folder: ${parentFolder})`);
2399
+ const reactor = window.ph?.reactorClientModule?.client;
2400
+ if (!reactor) {
2401
+ onProgress?.({
2402
+ stage: "failed",
2403
+ progress: 100,
2404
+ error: "ReactorClient not initialized"
2405
+ });
2406
+ throw new Error("ReactorClient not initialized");
2407
+ }
2408
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2409
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to create files");
2410
+ try {
2411
+ onProgress?.({
2412
+ stage: "loading",
2413
+ progress: 0
2414
+ });
2415
+ let document;
2416
+ try {
2417
+ document = await loadFile(file);
2418
+ } catch (loadError) {
2419
+ if (UnsupportedDocumentModelVersionError.isError(loadError)) {
2420
+ showPHModal({
2421
+ type: "documentVersionUnsupported",
2422
+ documentType: loadError.documentType,
2423
+ requiredVersion: loadError.requiredVersion,
2424
+ availableVersions: loadError.availableVersions
2425
+ });
2426
+ onProgress?.({
2427
+ stage: "failed",
2428
+ progress: 100,
2429
+ error: loadError.message
2430
+ });
2431
+ return;
2432
+ }
2433
+ const discoveryService = window.ph?.packageDiscoveryService;
2434
+ if (discoveryService && DocumentModelNotFoundError.isError(loadError)) {
2435
+ retryAfterDiscovery(discoveryService, loadError.documentType, file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict).catch((retryError) => {
2436
+ logger.error("Import retry after discovery failed: @error", retryError);
2437
+ onProgress?.({
2438
+ stage: "failed",
2439
+ progress: 100,
2440
+ error: retryError instanceof Error ? retryError.message : String(retryError)
2441
+ });
2442
+ });
2443
+ return;
2444
+ }
2445
+ throw loadError;
2446
+ }
2447
+ const duplicateCheck = await isDocumentInLocation(reactor, document, driveId, parentFolder);
2448
+ if (duplicateCheck.isDuplicate && !resolveConflict) {
2449
+ onProgress?.({
2450
+ stage: "conflict",
2451
+ progress: 0,
2452
+ duplicateType: duplicateCheck.duplicateType
2453
+ });
2454
+ return;
2455
+ }
2456
+ const documentType = getDocumentTypeIcon(document);
2457
+ if (documentType) onProgress?.({
2458
+ stage: "loading",
2459
+ progress: 10,
2460
+ documentType
2461
+ });
2462
+ else onProgress?.({
2463
+ stage: "loading",
2464
+ progress: 10
2465
+ });
2466
+ if (!isDocumentTypeSupported(document.header.documentType, documentTypes)) {
2467
+ onProgress?.({
2468
+ stage: "unsupported-document-type",
2469
+ progress: 100,
2470
+ error: `Document type ${document.header.documentType} is not supported`
2471
+ });
2472
+ throw new UnsupportedDocumentTypeError(document.header.documentType);
2473
+ }
2474
+ await reactor.getDocumentModelModule(document.header.documentType);
2475
+ onProgress?.({
2476
+ stage: "initializing",
2477
+ progress: 10
2478
+ });
2479
+ const created = await createImportedDocument(reactor, document, driveId, name, parentFolder);
2480
+ const documentId = created.documentId;
2481
+ const fileNode = created.fileNode;
2482
+ onProgress?.({
2483
+ stage: "initializing",
2484
+ progress: 20
2485
+ });
2486
+ await reactor.get(documentId);
2487
+ console.log("Document created, starting upload of operations");
2488
+ const segments = splitAtUpgradeBoundaries(document.operations);
2489
+ const totalOperations = segments.reduce((total, segment) => total + countOperations(segment.operations), 0);
2490
+ let uploadedBefore = 0;
2491
+ for (const segment of segments) {
2492
+ await uploadOperations(documentId, segment.operations, queueOperations, { onProgress: (uploadProgress) => {
2493
+ if (uploadProgress.uploadedOperations === void 0) return;
2494
+ const uploaded = uploadedBefore + uploadProgress.uploadedOperations;
2495
+ const uploadPercent = totalOperations > 0 ? uploaded / totalOperations : 0;
2496
+ onProgress?.({
2497
+ stage: "uploading",
2498
+ progress: 20 + Math.round(uploadPercent * 80),
2499
+ totalOperations,
2500
+ uploadedOperations: uploaded
2501
+ });
2502
+ } });
2503
+ uploadedBefore += countOperations(segment.operations);
2504
+ if (segment.upgradeTo !== void 0) await reactor.upgradeDocument(documentId, segment.upgradeTo);
2505
+ }
2506
+ onProgress?.({
2507
+ stage: "complete",
2508
+ progress: 100,
2509
+ fileNode
2510
+ });
2511
+ return fileNode;
2512
+ } catch (error) {
2513
+ if (!UnsupportedDocumentTypeError.isError(error)) {
2514
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
2515
+ onProgress?.({
2516
+ stage: "failed",
2517
+ progress: 100,
2518
+ error: errorMessage
2519
+ });
2520
+ }
2521
+ throw error;
2522
+ }
2748
2523
  }
2749
- /** Returns the current path without the base path */
2750
- function getPathWithoutBase(path) {
2751
- const basePath = window.ph?.basePath ?? "/";
2752
- return path.replace(basePath, basePath.endsWith("/") ? "/" : "");
2524
+ async function retryAfterDiscovery(discoveryService, documentType, file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict) {
2525
+ if (!discoveryService) return;
2526
+ try {
2527
+ await discoveryService.load(documentType);
2528
+ } catch {
2529
+ onProgress?.({
2530
+ stage: "unsupported-document-type",
2531
+ progress: 100,
2532
+ error: `Document type ${documentType} is not supported`
2533
+ });
2534
+ return;
2535
+ }
2536
+ await addFileWithProgress(file, driveId, name, parentFolder, onProgress, documentTypes, resolveConflict);
2753
2537
  }
2754
- /** Makes a URL component for a node. */
2755
- function makeNodeSlug(node) {
2756
- if (!node) return "";
2757
- const nodeName = node.name;
2758
- if (!nodeName) return slug(node.id);
2759
- return slug(`${nodeName}-${node.id}`);
2538
+ async function addFolder$1(driveId, name, parentFolder) {
2539
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2540
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to create folders");
2541
+ const reactorClient = window.ph?.reactorClient;
2542
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2543
+ await reactorClient.get(driveId);
2544
+ const folderId = generateId();
2545
+ const node = (await reactorClient.execute(driveId, "main", [addFolder({
2546
+ id: folderId,
2547
+ name,
2548
+ parentFolder
2549
+ })])).state.global.nodes.find((node) => node.id === folderId);
2550
+ if (!node || !isFolderNode(node)) throw new Error("There was an error adding folder");
2551
+ return node;
2760
2552
  }
2761
- /** Extracts the node slug from a path.
2762
- *
2763
- * The path is expected to be in the format `/d/<drive-slug>/<node-slug>`.
2764
- */
2765
- function extractNodeSlugFromPath(path) {
2766
- const currentPath = getPathWithoutBase(path);
2767
- return /^\/d\/[^/]+\/([^/]+)$/.exec(currentPath)?.[1];
2553
+ async function renameNode(driveId, nodeId, name) {
2554
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2555
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to rename documents");
2556
+ const reactorClient = window.ph?.reactorClient;
2557
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2558
+ if ((await reactorClient.execute(nodeId, "main", [setName({ name })])).header.name !== name) throw new Error("There was an error renaming the node");
2559
+ const node = (await reactorClient.execute(driveId, "main", [updateNode({
2560
+ id: nodeId,
2561
+ name
2562
+ })])).state.global.nodes.find((n) => n.id === nodeId);
2563
+ if (!node) throw new Error("There was an error renaming node in the drive");
2564
+ return node;
2768
2565
  }
2769
- /** Finds a UUID in a string, used for extracting node ids from node slugs in the URL. */
2770
- function findUuid(input) {
2771
- if (!input) return void 0;
2772
- return /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/.exec(input)?.[0];
2566
+ async function renameDriveNode(driveId, nodeId, name) {
2567
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2568
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to rename documents");
2569
+ const reactorClient = window.ph?.reactorClient;
2570
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2571
+ if ((await reactorClient.execute(nodeId, "main", [setName({ name })])).header.name !== name) throw new Error("There was an error renaming the node");
2572
+ await reactorClient.execute(driveId, "main", [updateNode({
2573
+ id: nodeId,
2574
+ name
2575
+ })]);
2576
+ return (await reactorClient.get(driveId)).state.global.nodes.find((n) => n.id === nodeId);
2773
2577
  }
2774
- function extractNodeIdFromSlug(nodeSlug) {
2775
- return findUuid(nodeSlug);
2578
+ async function moveNodeById(args) {
2579
+ const { driveId, srcId, targetId } = args;
2580
+ if (!driveId || !srcId) return;
2581
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2582
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to move documents");
2583
+ const reactorClient = window.ph?.reactorClient;
2584
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2585
+ const targetParentFolder = t$3(targetId, [e$3(e$4), e$6(void 0)], [t(driveId), e$6(void 0)], e$6(targetId));
2586
+ if (t(targetParentFolder, srcId)) return;
2587
+ return await reactorClient.execute(driveId, "main", [moveNode({
2588
+ srcFolder: srcId,
2589
+ targetParentFolder
2590
+ })]);
2776
2591
  }
2777
- /** Extracts the drive slug from a path.
2778
- * Used for extracting drive ids from drive slugs in the URL.
2779
- * Expects the path to be in the format `/d/<drive-slug>`.
2780
- */
2781
- function extractDriveSlugFromPath(path) {
2782
- const currentPath = getPathWithoutBase(path);
2783
- return /^\/d\/([^/]+)/.exec(currentPath)?.[1] ?? "";
2592
+ async function moveNode$1(driveId, src, target) {
2593
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2594
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to move documents");
2595
+ const reactorClient = window.ph?.reactorClient;
2596
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
2597
+ return await reactorClient.execute(driveId, "main", [moveNode({
2598
+ srcFolder: src.id,
2599
+ targetParentFolder: target?.id
2600
+ })]);
2784
2601
  }
2785
2602
  /**
2786
- * Creates a URL string with the given pathname while preserving existing query parameters.
2603
+ * Duplicates a document under a new id using version-aware replay.
2604
+ * Falls back gracefully when no upgrade manifest is registered for the document type.
2787
2605
  */
2788
- function createUrlWithPreservedParams(pathname) {
2789
- const search = window.location.search;
2790
- return search ? `${pathname}${search}` : pathname;
2791
- }
2792
- const drivesEventFunctions = makePHEventFunctions("drives");
2793
- /** Returns all of the drives in the reactor */
2794
- const useDrives = drivesEventFunctions.useValue;
2795
- /** Sets the drives in the reactor */
2796
- const setDrives = drivesEventFunctions.setValue;
2797
- drivesEventFunctions.addEventHandler;
2798
- const selectedNodeIdEventFunctions = makePHEventFunctions("selectedNodeId");
2799
- const useSelectedNodeId = selectedNodeIdEventFunctions.useValue;
2800
- const setSelectedNodeId = selectedNodeIdEventFunctions.setValue;
2801
- selectedNodeIdEventFunctions.addEventHandler;
2802
- /** Sets the selected node (file or folder). */
2803
- function setSelectedNode(nodeOrNodeSlug) {
2804
- const nodeSlug = typeof nodeOrNodeSlug === "string" ? nodeOrNodeSlug : makeNodeSlug(nodeOrNodeSlug);
2805
- setSelectedNodeId(extractNodeIdFromSlug(nodeSlug));
2806
- const driveSlugFromPath = extractDriveSlugFromPath(window.location.pathname);
2807
- if (!driveSlugFromPath) return;
2808
- if (!nodeSlug) {
2809
- const pathname = resolveUrlPathname(`/d/${driveSlugFromPath}`);
2810
- if (pathname === window.location.pathname) return;
2811
- window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
2812
- return;
2813
- }
2814
- const pathname = resolveUrlPathname(`/d/${driveSlugFromPath}/${nodeSlug}`);
2815
- if (pathname === window.location.pathname) return;
2816
- window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
2817
- }
2818
- const selectedDriveIdEventFunctions = makePHEventFunctions("selectedDriveId");
2819
- /** Returns the selected drive id */
2820
- const useSelectedDriveId = selectedDriveIdEventFunctions.useValue;
2821
- /** Sets the selected drive id */
2822
- const setSelectedDriveId = selectedDriveIdEventFunctions.setValue;
2823
- selectedDriveIdEventFunctions.addEventHandler;
2824
- /** Returns the selected drive, or undefined if no drive is selected */
2825
- function useSelectedDriveSafe() {
2826
- const selectedDriveId = useSelectedDriveId();
2827
- const selectedDrive = useDrives()?.find((drive) => drive.header.id === selectedDriveId);
2828
- const [drive, dispatch] = useDispatch(selectedDrive);
2829
- if (!selectedDrive) return [void 0, void 0];
2830
- return [drive, dispatch];
2831
- }
2832
- function setSelectedDrive(driveOrDriveSlug) {
2833
- const driveSlug = typeof driveOrDriveSlug === "string" ? driveOrDriveSlug : driveOrDriveSlug?.header.slug;
2834
- const drives = window.ph?.drives;
2835
- const driveId = (typeof driveOrDriveSlug === "object" && driveOrDriveSlug !== null ? driveOrDriveSlug : drives?.find((d) => d.header.slug === driveSlug))?.header.id;
2836
- if (!driveId && driveSlug && extractDriveSlugFromPath(window.location.pathname) === driveSlug) {
2837
- if (window.ph?.selectedDriveId) setSelectedDriveId(void 0);
2838
- deferDriveSelection(driveSlug);
2839
- return;
2840
- }
2841
- cancelPendingDriveSelection();
2842
- setSelectedDriveId(driveId);
2843
- if (!driveId) {
2844
- const pathname = resolveUrlPathname("/");
2845
- if (pathname === window.location.pathname) return;
2846
- window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
2847
- return;
2848
- }
2849
- const pathname = resolveUrlPathname(`/d/${driveSlug}`);
2850
- if (pathname === window.location.pathname) return;
2851
- window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
2606
+ async function _duplicateDocument(reactor, document, newId = generateId()) {
2607
+ const documentType = document.header.documentType;
2608
+ const { results: allModules } = await reactor.getDocumentModelModules();
2609
+ const modulesForType = allModules.filter((m) => m.documentModel.global.id === documentType);
2610
+ const reducers = {};
2611
+ for (const m of modulesForType) reducers[m.version ?? 1] = m.reducer;
2612
+ if (Object.keys(reducers).length === 0) throw new Error(`Document model module not found for type: ${documentType}`);
2613
+ const registry = window.ph?.reactorClientModule?.reactorModule?.documentModelRegistry;
2614
+ let upgradeManifest;
2615
+ if (registry) try {
2616
+ upgradeManifest = registry.getUpgradeManifest(documentType);
2617
+ } catch {}
2618
+ const config = {
2619
+ reducers,
2620
+ upgradeManifest
2621
+ };
2622
+ const header = createPresignedHeader(newId, documentType);
2623
+ const duplicated = replayDocumentVersioned(document.initialState, document.operations, config, header);
2624
+ assertAuthPreservedOnDuplicate(document.header.id, document.state.auth, duplicated.state.auth);
2625
+ return duplicated;
2852
2626
  }
2853
- const DEFERRED_DRIVE_TICK_MS = 2e3;
2854
- const DEFERRED_DRIVE_MAX_WAIT_MS = 15e3;
2855
- function isInitialSyncInFlight() {
2856
- const remotes = window.ph?.reactorClientModule?.reactorModule?.syncModule?.syncManager?.list();
2857
- if (!remotes?.length) return false;
2858
- return remotes.some((remote) => {
2859
- try {
2860
- const snapshot = remote.channel.getConnectionState();
2861
- return snapshot.receivingPages || !snapshot.lastSuccessUtcMs && snapshot.state !== "error";
2862
- } catch {
2863
- return false;
2627
+ async function copyNode$1(driveId, src, target) {
2628
+ const reactor = window.ph?.reactorClientModule?.client;
2629
+ if (!reactor) return;
2630
+ const { isAllowedToCreateDocuments } = getUserPermissions();
2631
+ if (!isAllowedToCreateDocuments) throw new Error("User is not allowed to copy documents");
2632
+ const drive = await reactor.get(driveId);
2633
+ const copyNodesInput = generateNodesCopy({
2634
+ srcId: src.id,
2635
+ targetParentFolder: target?.id,
2636
+ targetName: src.name
2637
+ }, () => generateId(), drive.state.global.nodes);
2638
+ const resolvedNamesMap = /* @__PURE__ */ new Map();
2639
+ for (const copyNodeInput of copyNodesInput) {
2640
+ const node = drive.state.global.nodes.find((n) => n.id === copyNodeInput.srcId);
2641
+ if (node) {
2642
+ const resolvedName = handleTargetNameCollisions({
2643
+ nodes: drive.state.global.nodes,
2644
+ srcName: copyNodeInput.targetName || node.name,
2645
+ srcKind: isFileNode(node) ? "file" : "folder",
2646
+ targetParentFolder: copyNodeInput.targetParentFolder || null
2647
+ });
2648
+ resolvedNamesMap.set(copyNodeInput.targetId, resolvedName);
2864
2649
  }
2865
- });
2866
- }
2867
- let pendingHandler;
2868
- let pendingTimeout;
2869
- function cancelPendingDriveSelection() {
2870
- if (pendingHandler) {
2871
- window.removeEventListener("ph:drivesUpdated", pendingHandler);
2872
- pendingHandler = void 0;
2873
2650
  }
2874
- if (pendingTimeout) {
2875
- clearTimeout(pendingTimeout);
2876
- pendingTimeout = void 0;
2651
+ const fileNodesToCopy = copyNodesInput.filter((copyNodeInput) => {
2652
+ const node = drive.state.global.nodes.find((node) => node.id === copyNodeInput.srcId);
2653
+ return node !== void 0 && isFileNode(node);
2654
+ });
2655
+ for (const fileNodeToCopy of fileNodesToCopy) try {
2656
+ const duplicatedDocument = await _duplicateDocument(reactor, await reactor.get(fileNodeToCopy.srcId), fileNodeToCopy.targetId);
2657
+ const resolvedName = resolvedNamesMap.get(fileNodeToCopy.targetId);
2658
+ if (resolvedName) duplicatedDocument.header.name = resolvedName;
2659
+ await reactor.drives.addFile(driveId, duplicatedDocument, target?.id);
2660
+ } catch (e) {
2661
+ logger.error(`Error copying document ${fileNodeToCopy.srcId}: ${String(e)}`);
2877
2662
  }
2663
+ return await queueActions(drive, copyNodesInput.map((copyNodeInput) => copyNode(copyNodeInput)));
2878
2664
  }
2879
- function deferDriveSelection(driveSlug) {
2880
- cancelPendingDriveSelection();
2881
- const nodeSlug = extractNodeSlugFromPath(window.location.pathname);
2882
- const handler = () => {
2883
- if (!window.ph?.drives?.find((d) => d.header.slug === driveSlug)) return;
2884
- cancelPendingDriveSelection();
2885
- setSelectedDrive(driveSlug);
2886
- setSelectedNode(nodeSlug);
2887
- };
2888
- pendingHandler = handler;
2889
- window.addEventListener("ph:drivesUpdated", handler);
2890
- const deadline = Date.now() + DEFERRED_DRIVE_MAX_WAIT_MS;
2891
- const scheduleTick = () => {
2892
- pendingTimeout = setTimeout(() => {
2893
- if (Date.now() < deadline && isInitialSyncInFlight()) {
2894
- scheduleTick();
2895
- return;
2896
- }
2897
- cancelPendingDriveSelection();
2898
- const pathname = resolveUrlPathname("/");
2899
- if (pathname === window.location.pathname) return;
2900
- window.history.pushState(null, "", createUrlWithPreservedParams(pathname));
2901
- }, DEFERRED_DRIVE_TICK_MS);
2902
- };
2903
- scheduleTick();
2665
+ gql`
2666
+ mutation MutateDocumentWithOperations(
2667
+ $documentIdentifier: String!
2668
+ $actions: [ActionInput!]!
2669
+ $sinceRevision: Int
2670
+ $scopes: [String!]
2671
+ $branch: String
2672
+ ) {
2673
+ mutateDocument: execute(
2674
+ documentIdentifier: $documentIdentifier
2675
+ actions: $actions
2676
+ branch: $branch
2677
+ ) {
2678
+ ...PHDocumentFields
2679
+ operations(
2680
+ filter: {
2681
+ sinceRevision: $sinceRevision
2682
+ scopes: $scopes
2683
+ branch: $branch
2684
+ }
2685
+ ) {
2686
+ items {
2687
+ ...ReactorOperationFields
2688
+ }
2689
+ }
2690
+ }
2691
+ }
2692
+ ${PhDocumentFieldsFragmentDoc}
2693
+ ${gql`
2694
+ fragment ReactorOperationFields on ReactorOperation {
2695
+ index
2696
+ timestampUtcMs
2697
+ hash
2698
+ skip
2699
+ error
2700
+ deniedReason
2701
+ id
2702
+ action {
2703
+ id
2704
+ type
2705
+ timestampUtcMs
2706
+ input
2707
+ scope
2708
+ context {
2709
+ signer {
2710
+ user {
2711
+ address
2712
+ networkId
2713
+ chainId
2714
+ }
2715
+ app {
2716
+ name
2717
+ key
2718
+ }
2719
+ signatures
2720
+ }
2721
+ }
2722
+ }
2723
+ }
2724
+ `}
2725
+ `;
2726
+ DocumentChangeType.Created, DOCUMENT_CHANGE_TYPE.Created, DocumentChangeType.Deleted, DOCUMENT_CHANGE_TYPE.Deleted, DocumentChangeType.Updated, DOCUMENT_CHANGE_TYPE.Updated, DocumentChangeType.ParentAdded, DOCUMENT_CHANGE_TYPE.ParentAdded, DocumentChangeType.ParentRemoved, DOCUMENT_CHANGE_TYPE.ParentRemoved, DocumentChangeType.ChildAdded, DOCUMENT_CHANGE_TYPE.ChildAdded, DocumentChangeType.ChildRemoved, DOCUMENT_CHANGE_TYPE.ChildRemoved;
2727
+ PropagationMode.Cascade, PropagationMode.Orphan;
2728
+ const isExternalControlsEnabledEventFunctions = makePHEventFunctions("isExternalControlsEnabled");
2729
+ /** Sets whether external controls are enabled for a given editor. */
2730
+ const setIsExternalControlsEnabled = isExternalControlsEnabledEventFunctions.setValue;
2731
+ /** Gets whether external controls are enabled for a given editor. */
2732
+ const useIsExternalControlsEnabled = isExternalControlsEnabledEventFunctions.useValue;
2733
+ isExternalControlsEnabledEventFunctions.addEventHandler;
2734
+ const isDragAndDropEnabledEventFunctions = makePHEventFunctions("isDragAndDropEnabled");
2735
+ /** Sets whether drag and drop is enabled for a given app. */
2736
+ const setIsDragAndDropEnabled = isDragAndDropEnabledEventFunctions.setValue;
2737
+ /** Gets whether drag and drop is enabled for a given app. */
2738
+ const useIsDragAndDropEnabled = isDragAndDropEnabledEventFunctions.useValue;
2739
+ isDragAndDropEnabledEventFunctions.addEventHandler;
2740
+ const allowedDocumentTypesEventFunctions = makePHEventFunctions("allowedDocumentTypes");
2741
+ /** Sets the allowed document types for a given app. */
2742
+ const setAllowedDocumentTypes = allowedDocumentTypesEventFunctions.setValue;
2743
+ /** Defines the document types a drive supports.
2744
+ *
2745
+ * Defaults to all of the document types registered in the reactor.
2746
+ */
2747
+ function useAllowedDocumentTypes() {
2748
+ return allowedDocumentTypesEventFunctions.useValue();
2904
2749
  }
2750
+ allowedDocumentTypesEventFunctions.addEventHandler;
2751
+ const phAppConfigSetters = {
2752
+ allowedDocumentTypes: setAllowedDocumentTypes,
2753
+ isDragAndDropEnabled: setIsDragAndDropEnabled
2754
+ };
2755
+ const phDocumentEditorConfigSetters = { isExternalControlsEnabled: setIsExternalControlsEnabled };
2756
+ const phAppConfigHooks = {
2757
+ allowedDocumentTypes: useAllowedDocumentTypes,
2758
+ isDragAndDropEnabled: useIsDragAndDropEnabled
2759
+ };
2760
+ const phDocumentEditorConfigHooks = { isExternalControlsEnabled: useIsExternalControlsEnabled };
2761
+ const { useValue: useRouterBasename, setValue: setRouterBasename, addEventHandler: addRouterBasenameEventHandler } = makePHEventFunctions("routerBasename");
2762
+ const { useValue: useVersion, setValue: setVersion, addEventHandler: addVersionEventHandler } = makePHEventFunctions("version");
2763
+ const { useValue: useRequiresHardRefresh, setValue: setRequiresHardRefresh, addEventHandler: addRequiresHardRefreshEventHandler } = makePHEventFunctions("requiresHardRefresh");
2764
+ const { useValue: useWarnOutdatedApp, setValue: setWarnOutdatedApp, addEventHandler: addWarnOutdatedAppEventHandler } = makePHEventFunctions("warnOutdatedApp");
2765
+ const { useValue: useStudioMode, setValue: setStudioMode, addEventHandler: addStudioModeEventHandler } = makePHEventFunctions("studioMode");
2766
+ const { useValue: useBasePath, setValue: setBasePath, addEventHandler: addBasePathEventHandler } = makePHEventFunctions("basePath");
2767
+ const { useValue: useVersionCheckInterval, setValue: setVersionCheckInterval, addEventHandler: addVersionCheckIntervalEventHandler } = makePHEventFunctions("versionCheckInterval");
2768
+ const { useValue: useCliVersion, setValue: setCliVersion, addEventHandler: addCliVersionEventHandler } = makePHEventFunctions("cliVersion");
2769
+ const { useValue: useFileUploadOperationsChunkSize, setValue: setFileUploadOperationsChunkSize, addEventHandler: addFileUploadOperationsChunkSizeEventHandler } = makePHEventFunctions("fileUploadOperationsChunkSize");
2770
+ const { useValue: useIsDocumentModelSelectionSettingsEnabled, setValue: setIsDocumentModelSelectionSettingsEnabled, addEventHandler: addIsDocumentModelSelectionSettingsEnabledEventHandler } = makePHEventFunctions("isDocumentModelSelectionSettingsEnabled");
2771
+ const { useValue: useGaTrackingId, setValue: setGaTrackingId, addEventHandler: addGaTrackingIdEventHandler } = makePHEventFunctions("gaTrackingId");
2772
+ const { useValue: useDefaultDrivesUrl, setValue: setDefaultDrivesUrl, addEventHandler: addDefaultDrivesUrlEventHandler } = makePHEventFunctions("defaultDrivesUrl");
2773
+ const { useValue: useDrivesPreserveStrategy, setValue: setDrivesPreserveStrategy, addEventHandler: addDrivesPreserveStrategyEventHandler } = makePHEventFunctions("drivesPreserveStrategy");
2774
+ const { useValue: useIsLocalDrivesEnabled, setValue: setIsLocalDrivesEnabled, addEventHandler: addIsLocalDrivesEnabledEventHandler } = makePHEventFunctions("isLocalDrivesEnabled");
2775
+ const { useValue: useIsAddDriveEnabled, setValue: setIsAddDriveEnabled, addEventHandler: addIsAddDriveEnabledEventHandler } = makePHEventFunctions("isAddDriveEnabled");
2776
+ const { useValue: useIsPublicDrivesEnabled, setValue: setIsPublicDrivesEnabled, addEventHandler: addIsPublicDrivesEnabledEventHandler } = makePHEventFunctions("isPublicDrivesEnabled");
2777
+ const { useValue: useIsAddPublicDrivesEnabled, setValue: setIsAddPublicDrivesEnabled, addEventHandler: addIsAddPublicDrivesEnabledEventHandler } = makePHEventFunctions("isAddPublicDrivesEnabled");
2778
+ const { useValue: useIsDeletePublicDrivesEnabled, setValue: setIsDeletePublicDrivesEnabled, addEventHandler: addIsDeletePublicDrivesEnabledEventHandler } = makePHEventFunctions("isDeletePublicDrivesEnabled");
2779
+ const { useValue: useIsCloudDrivesEnabled, setValue: setIsCloudDrivesEnabled, addEventHandler: addIsCloudDrivesEnabledEventHandler } = makePHEventFunctions("isCloudDrivesEnabled");
2780
+ const { useValue: useIsAddCloudDrivesEnabled, setValue: setIsAddCloudDrivesEnabled, addEventHandler: addIsAddCloudDrivesEnabledEventHandler } = makePHEventFunctions("isAddCloudDrivesEnabled");
2781
+ const { useValue: useIsDeleteCloudDrivesEnabled, setValue: setIsDeleteCloudDrivesEnabled, addEventHandler: addIsDeleteCloudDrivesEnabledEventHandler } = makePHEventFunctions("isDeleteCloudDrivesEnabled");
2782
+ const { useValue: useLocalDrivesEnabled, setValue: setLocalDrivesEnabled, addEventHandler: addLocalDrivesEnabledEventHandler } = makePHEventFunctions("isLocalDrivesEnabled");
2783
+ const { useValue: useIsAddLocalDrivesEnabled, setValue: setIsAddLocalDrivesEnabled, addEventHandler: addIsAddLocalDrivesEnabledEventHandler } = makePHEventFunctions("isAddLocalDrivesEnabled");
2784
+ const { useValue: useIsDeleteLocalDrivesEnabled, setValue: setIsDeleteLocalDrivesEnabled, addEventHandler: addIsDeleteLocalDrivesEnabledEventHandler } = makePHEventFunctions("isDeleteLocalDrivesEnabled");
2785
+ const { useValue: useIsEditorDebugModeEnabled, setValue: setIsEditorDebugModeEnabled, addEventHandler: addIsEditorDebugModeEnabledEventHandler } = makePHEventFunctions("isEditorDebugModeEnabled");
2786
+ const { useValue: useIsEditorReadModeEnabled, setValue: setIsEditorReadModeEnabled, addEventHandler: addIsEditorReadModeEnabledEventHandler } = makePHEventFunctions("isEditorReadModeEnabled");
2787
+ const { useValue: useIsAnalyticsDatabaseWorkerEnabled, setValue: setIsAnalyticsDatabaseWorkerEnabled, addEventHandler: addIsAnalyticsDatabaseWorkerEnabledEventHandler } = makePHEventFunctions("isAnalyticsDatabaseWorkerEnabled");
2788
+ const { useValue: useIsDiffAnalyticsEnabled, setValue: setIsDiffAnalyticsEnabled, addEventHandler: addIsDiffAnalyticsEnabledEventHandler } = makePHEventFunctions("isDiffAnalyticsEnabled");
2789
+ const { useValue: useIsDriveAnalyticsEnabled, setValue: setIsDriveAnalyticsEnabled, addEventHandler: addIsDriveAnalyticsEnabledEventHandler } = makePHEventFunctions("isDriveAnalyticsEnabled");
2790
+ const { useValue: useRenownUrl, setValue: setRenownUrl, addEventHandler: addRenownUrlEventHandler } = makePHEventFunctions("renownUrl");
2791
+ const { useValue: useRenownNetworkId, setValue: setRenownNetworkId, addEventHandler: addRenownNetworkIdEventHandler } = makePHEventFunctions("renownNetworkId");
2792
+ const { useValue: useRenownChainId, setValue: setRenownChainId, addEventHandler: addRenownChainIdEventHandler } = makePHEventFunctions("renownChainId");
2793
+ const { useValue: useSwitchboardUrl, setValue: setSwitchboardUrl, addEventHandler: addSwitchboardUrlEventHandler } = makePHEventFunctions("switchboardUrl");
2794
+ const { useValue: useRenownAdapters, setValue: setRenownAdapters, addEventHandler: addRenownAdaptersEventHandler } = makePHEventFunctions("renownAdapters");
2795
+ const { useValue: useSentryRelease, setValue: setSentryRelease, addEventHandler: addSentryReleaseEventHandler } = makePHEventFunctions("sentryRelease");
2796
+ const { useValue: useSentryDsn, setValue: setSentryDsn, addEventHandler: addSentryDsnEventHandler } = makePHEventFunctions("sentryDsn");
2797
+ const { useValue: useSentryEnv, setValue: setSentryEnv, addEventHandler: addSentryEnvEventHandler } = makePHEventFunctions("sentryEnv");
2798
+ const { useValue: useIsSentryTracingEnabled, setValue: setIsSentryTracingEnabled, addEventHandler: addIsSentryTracingEnabledEventHandler } = makePHEventFunctions("isSentryTracingEnabled");
2799
+ const { useValue: useIsExternalProcessorsEnabled, setValue: setIsExternalProcessorsEnabled, addEventHandler: addIsExternalProcessorsEnabledEventHandler } = makePHEventFunctions("isExternalProcessorsEnabled");
2800
+ const { useValue: useIsExternalPackagesEnabled, setValue: setIsExternalPackagesEnabled, addEventHandler: addIsExternalPackagesEnabledEventHandler } = makePHEventFunctions("isExternalPackagesEnabled");
2801
+ const enabledEditorsEventFunctions = makePHEventFunctions("enabledEditors");
2802
+ /** Sets the enabled editors for Connect. */
2803
+ const setEnabledEditors = enabledEditorsEventFunctions.setValue;
2804
+ /** Gets the enabled editors for Connect. */
2805
+ const useEnabledEditors = enabledEditorsEventFunctions.useValue;
2806
+ enabledEditorsEventFunctions.addEventHandler;
2807
+ const disabledEditorsEventFunctions = makePHEventFunctions("disabledEditors");
2808
+ /** Sets the disabled editors for Connect. */
2809
+ const setDisabledEditors = disabledEditorsEventFunctions.setValue;
2810
+ /** Gets the disabled editors for Connect. */
2811
+ const useDisabledEditors = disabledEditorsEventFunctions.useValue;
2812
+ disabledEditorsEventFunctions.addEventHandler;
2813
+ const isRelationalProcessorsEnabled = makePHEventFunctions("isRelationalProcessorsEnabled");
2814
+ /** Sets the isRelationalProcessorsEnabled for Connect. */
2815
+ const setIsRelationalProcessorsEnabled = isRelationalProcessorsEnabled.setValue;
2816
+ /** Gets the isRelationalProcessorsEnabled for Connect. */
2817
+ const useIsRelationalProcessorsEnabled = isRelationalProcessorsEnabled.useValue;
2818
+ isRelationalProcessorsEnabled.addEventHandler;
2819
+ const isExternalRelationalProcessorsEnabled = makePHEventFunctions("isExternalRelationalProcessorsEnabled");
2820
+ /** Sets the isExternalRelationalProcessorsEnabled for Connect. */
2821
+ const setIsExternalRelationalProcessorsEnabled = isExternalRelationalProcessorsEnabled.setValue;
2822
+ /** Gets the isExternalRelationalProcessorsEnabled for Connect. */
2823
+ const useIsExternalRelationalProcessorsEnabled = isExternalRelationalProcessorsEnabled.useValue;
2824
+ isExternalRelationalProcessorsEnabled.addEventHandler;
2825
+ const isAnalyticsEnabledEventFunctions = makePHEventFunctions("isAnalyticsEnabled");
2826
+ /** Sets the isAnalyticsEnabled for Connect. */
2827
+ const setIsAnalyticsEnabled = isAnalyticsEnabledEventFunctions.setValue;
2828
+ /** Gets the isAnalyticsEnabled for Connect. */
2829
+ const useIsAnalyticsEnabled = isAnalyticsEnabledEventFunctions.useValue;
2830
+ isAnalyticsEnabledEventFunctions.addEventHandler;
2831
+ const isAnalyticsExternalProcessorsEnabled = makePHEventFunctions("isAnalyticsExternalProcessorsEnabled");
2832
+ /** Sets the isAnalyticsExternalProcessorsEnabled for Connect. */
2833
+ const setIsAnalyticsExternalProcessorsEnabled = isAnalyticsExternalProcessorsEnabled.setValue;
2834
+ /** Gets the isAnalyticsExternalProcessorsEnabled for Connect. */
2835
+ const useIsAnalyticsExternalProcessorsEnabled = isAnalyticsExternalProcessorsEnabled.useValue;
2836
+ isAnalyticsExternalProcessorsEnabled.addEventHandler;
2837
+ const analyticsDatabaseNameEventFunctions = makePHEventFunctions("analyticsDatabaseName");
2838
+ /** Sets the analytics database name for Connect. */
2839
+ const setAnalyticsDatabaseName = analyticsDatabaseNameEventFunctions.setValue;
2840
+ /** Gets the analytics database name for Connect. */
2841
+ const useAnalyticsDatabaseName = analyticsDatabaseNameEventFunctions.useValue;
2842
+ analyticsDatabaseNameEventFunctions.addEventHandler;
2843
+ const logLevelEventFunctions = makePHEventFunctions("logLevel");
2844
+ /** Sets the log level for Connect. */
2845
+ const setLogLevel = logLevelEventFunctions.setValue;
2846
+ /** Gets the log level for Connect. */
2847
+ const useLogLevel = logLevelEventFunctions.useValue;
2848
+ logLevelEventFunctions.addEventHandler;
2849
+ const allowListEventFunctions = makePHEventFunctions("allowList");
2850
+ /** Sets the allow list for Connect. */
2851
+ const setAllowList = allowListEventFunctions.setValue;
2852
+ /** Gets the allow list for Connect. */
2853
+ const useAllowList = allowListEventFunctions.useValue;
2854
+ allowListEventFunctions.addEventHandler;
2855
+ const nonUserConfigSetters = {
2856
+ routerBasename: setRouterBasename,
2857
+ version: setVersion,
2858
+ requiresHardRefresh: setRequiresHardRefresh,
2859
+ warnOutdatedApp: setWarnOutdatedApp,
2860
+ studioMode: setStudioMode,
2861
+ basePath: setBasePath,
2862
+ versionCheckInterval: setVersionCheckInterval,
2863
+ cliVersion: setCliVersion,
2864
+ fileUploadOperationsChunkSize: setFileUploadOperationsChunkSize,
2865
+ isDocumentModelSelectionSettingsEnabled: setIsDocumentModelSelectionSettingsEnabled,
2866
+ gaTrackingId: setGaTrackingId,
2867
+ defaultDrivesUrl: setDefaultDrivesUrl,
2868
+ drivesPreserveStrategy: setDrivesPreserveStrategy,
2869
+ isLocalDrivesEnabled: setIsLocalDrivesEnabled,
2870
+ isAddDriveEnabled: setIsAddDriveEnabled,
2871
+ isPublicDrivesEnabled: setIsPublicDrivesEnabled,
2872
+ isAddPublicDrivesEnabled: setIsAddPublicDrivesEnabled,
2873
+ isDeletePublicDrivesEnabled: setIsDeletePublicDrivesEnabled,
2874
+ isCloudDrivesEnabled: setIsCloudDrivesEnabled,
2875
+ isAddCloudDrivesEnabled: setIsAddCloudDrivesEnabled,
2876
+ isDeleteCloudDrivesEnabled: setIsDeleteCloudDrivesEnabled,
2877
+ isAddLocalDrivesEnabled: setIsAddLocalDrivesEnabled,
2878
+ isDeleteLocalDrivesEnabled: setIsDeleteLocalDrivesEnabled,
2879
+ isEditorDebugModeEnabled: setIsEditorDebugModeEnabled,
2880
+ isEditorReadModeEnabled: setIsEditorReadModeEnabled,
2881
+ isRelationalProcessorsEnabled: setIsRelationalProcessorsEnabled,
2882
+ isExternalRelationalProcessorsEnabled: setIsExternalRelationalProcessorsEnabled,
2883
+ isAnalyticsEnabled: setIsAnalyticsEnabled,
2884
+ analyticsDatabaseName: setAnalyticsDatabaseName,
2885
+ isAnalyticsExternalProcessorsEnabled: setIsAnalyticsExternalProcessorsEnabled,
2886
+ isAnalyticsDatabaseWorkerEnabled: setIsAnalyticsDatabaseWorkerEnabled,
2887
+ isDiffAnalyticsEnabled: setIsDiffAnalyticsEnabled,
2888
+ isDriveAnalyticsEnabled: setIsDriveAnalyticsEnabled,
2889
+ renownUrl: setRenownUrl,
2890
+ renownNetworkId: setRenownNetworkId,
2891
+ renownChainId: setRenownChainId,
2892
+ switchboardUrl: setSwitchboardUrl,
2893
+ renownAdapters: setRenownAdapters,
2894
+ sentryRelease: setSentryRelease,
2895
+ sentryDsn: setSentryDsn,
2896
+ sentryEnv: setSentryEnv,
2897
+ isSentryTracingEnabled: setIsSentryTracingEnabled,
2898
+ isExternalProcessorsEnabled: setIsExternalProcessorsEnabled,
2899
+ isExternalPackagesEnabled: setIsExternalPackagesEnabled,
2900
+ allowList: setAllowList,
2901
+ logLevel: setLogLevel,
2902
+ disabledEditors: setDisabledEditors,
2903
+ enabledEditors: setEnabledEditors
2904
+ };
2905
+ const phGlobalConfigSetters = {
2906
+ ...phAppConfigSetters,
2907
+ ...phDocumentEditorConfigSetters,
2908
+ ...nonUserConfigSetters
2909
+ };
2910
+ const nonUserConfigHooks = {
2911
+ routerBasename: useRouterBasename,
2912
+ version: useVersion,
2913
+ requiresHardRefresh: useRequiresHardRefresh,
2914
+ warnOutdatedApp: useWarnOutdatedApp,
2915
+ studioMode: useStudioMode,
2916
+ basePath: useBasePath,
2917
+ versionCheckInterval: useVersionCheckInterval,
2918
+ cliVersion: useCliVersion,
2919
+ fileUploadOperationsChunkSize: useFileUploadOperationsChunkSize,
2920
+ isDocumentModelSelectionSettingsEnabled: useIsDocumentModelSelectionSettingsEnabled,
2921
+ gaTrackingId: useGaTrackingId,
2922
+ defaultDrivesUrl: useDefaultDrivesUrl,
2923
+ drivesPreserveStrategy: useDrivesPreserveStrategy,
2924
+ isAddDriveEnabled: useIsAddDriveEnabled,
2925
+ isPublicDrivesEnabled: useIsPublicDrivesEnabled,
2926
+ isAddPublicDrivesEnabled: useIsAddPublicDrivesEnabled,
2927
+ isDeletePublicDrivesEnabled: useIsDeletePublicDrivesEnabled,
2928
+ isCloudDrivesEnabled: useIsCloudDrivesEnabled,
2929
+ isAddCloudDrivesEnabled: useIsAddCloudDrivesEnabled,
2930
+ isDeleteCloudDrivesEnabled: useIsDeleteCloudDrivesEnabled,
2931
+ isLocalDrivesEnabled: useIsLocalDrivesEnabled,
2932
+ isAddLocalDrivesEnabled: useIsAddLocalDrivesEnabled,
2933
+ isDeleteLocalDrivesEnabled: useIsDeleteLocalDrivesEnabled,
2934
+ isEditorDebugModeEnabled: useIsEditorDebugModeEnabled,
2935
+ isEditorReadModeEnabled: useIsEditorReadModeEnabled,
2936
+ isAnalyticsDatabaseWorkerEnabled: useIsAnalyticsDatabaseWorkerEnabled,
2937
+ isDiffAnalyticsEnabled: useIsDiffAnalyticsEnabled,
2938
+ isDriveAnalyticsEnabled: useIsDriveAnalyticsEnabled,
2939
+ renownUrl: useRenownUrl,
2940
+ renownNetworkId: useRenownNetworkId,
2941
+ renownChainId: useRenownChainId,
2942
+ switchboardUrl: useSwitchboardUrl,
2943
+ renownAdapters: useRenownAdapters,
2944
+ sentryRelease: useSentryRelease,
2945
+ sentryDsn: useSentryDsn,
2946
+ sentryEnv: useSentryEnv,
2947
+ isSentryTracingEnabled: useIsSentryTracingEnabled,
2948
+ isExternalProcessorsEnabled: useIsExternalProcessorsEnabled,
2949
+ isExternalPackagesEnabled: useIsExternalPackagesEnabled,
2950
+ allowList: useAllowList,
2951
+ isAnalyticsEnabled: useIsAnalyticsEnabled,
2952
+ isAnalyticsExternalProcessorsEnabled: useIsAnalyticsExternalProcessorsEnabled,
2953
+ isRelationalProcessorsEnabled: useIsRelationalProcessorsEnabled,
2954
+ isExternalRelationalProcessorsEnabled: useIsExternalRelationalProcessorsEnabled,
2955
+ analyticsDatabaseName: useAnalyticsDatabaseName,
2956
+ logLevel: useLogLevel,
2957
+ disabledEditors: useDisabledEditors,
2958
+ enabledEditors: useEnabledEditors
2959
+ };
2960
+ ({
2961
+ ...phAppConfigHooks,
2962
+ ...phDocumentEditorConfigHooks,
2963
+ ...nonUserConfigHooks
2964
+ });
2965
+ const attachmentServiceEventFunctions = makePHEventFunctions("attachmentService");
2966
+ attachmentServiceEventFunctions.useValue;
2967
+ attachmentServiceEventFunctions.setValue;
2968
+ attachmentServiceEventFunctions.addEventHandler;
2969
+ const featuresEventFunctions = makePHEventFunctions("features");
2970
+ featuresEventFunctions.useValue;
2971
+ featuresEventFunctions.setValue;
2972
+ featuresEventFunctions.addEventHandler;
2905
2973
  function useDropTarget() {
2906
2974
  const [isDropTarget, setIsDropTarget] = useState(false);
2907
2975
  const isDragAndDropEnabled = useIsDragAndDropEnabled();
@@ -3049,34 +3117,6 @@ revisionHistoryEventFunctions.addEventHandler;
3049
3117
  function showRevisionHistory() {
3050
3118
  setRevisionHistoryVisible(true);
3051
3119
  }
3052
- /** Sorts nodes by name. */
3053
- function sortNodesByName(nodes) {
3054
- return nodes.toSorted((a, b) => a.name.localeCompare(b.name));
3055
- }
3056
- /** Returns whether a node is a file. */
3057
- function isFileNodeKind(node) {
3058
- if (!node) return false;
3059
- return node.kind.toUpperCase() === "FILE";
3060
- }
3061
- /** Returns whether a node is a folder. */
3062
- function isFolderNodeKind(node) {
3063
- if (!node) return false;
3064
- return node.kind.toUpperCase() === "FOLDER";
3065
- }
3066
- /** Returns the nodes in the selected drive. */
3067
- function useNodesInSelectedDrive() {
3068
- const [selectedDrive] = useSelectedDriveSafe();
3069
- return selectedDrive?.state.global.nodes;
3070
- }
3071
- /** Returns the folder nodes in the selected drive. */
3072
- function useFolderNodesInSelectedDrive() {
3073
- return useNodesInSelectedDrive()?.filter((n) => isFolderNodeKind(n));
3074
- }
3075
- /** Returns the selected node. */
3076
- function useSelectedNode() {
3077
- const selectedNodeId = useSelectedNodeId();
3078
- return useNodesInSelectedDrive()?.find((n) => n.id === selectedNodeId);
3079
- }
3080
3120
  const selectedTimelineItemEventFunctions = makePHEventFunctions("selectedTimelineItem");
3081
3121
  selectedTimelineItemEventFunctions.useValue;
3082
3122
  selectedTimelineItemEventFunctions.setValue;
@@ -3090,43 +3130,32 @@ const toastEventFunctions = makePHEventFunctions("toast");
3090
3130
  const usePHToast = toastEventFunctions.useValue;
3091
3131
  toastEventFunctions.setValue;
3092
3132
  toastEventFunctions.addEventHandler;
3093
- const vetraPackageManagerFunctions = makePHEventFunctions("vetraPackageManager");
3094
- const useVetraPackageManager = vetraPackageManagerFunctions.useValue;
3095
- /** Returns all of the Vetra packages loaded by the Connect instance */
3096
- const useVetraPackages = () => {
3097
- const packageManager = useVetraPackageManager();
3098
- return useSyncExternalStore((cb) => packageManager ? packageManager.subscribe(cb) : () => {}, () => packageManager?.packages ?? []);
3099
- };
3100
- vetraPackageManagerFunctions.addEventHandler;
3101
- function useDocumentModelModules() {
3102
- return useVetraPackages().flatMap((pkg) => pkg.documentModels).filter((module, index, modules) => modules.findIndex((m) => m.documentModel.global.id === module.documentModel.global.id && m.version === module.version) === index);
3133
+ //#endregion
3134
+ //#region ../reactor-browser/dist/selected-document-CtRlEZyi.js
3135
+ /** Returns a document of a specific type, throws an error if the found document has a different type */
3136
+ function useDocumentOfType(documentId, documentType) {
3137
+ const [document, dispatch] = useDocumentById(documentId);
3138
+ const documentModelModule = useDocumentModelModuleById(documentType);
3139
+ if (!documentId || !documentType) return [];
3140
+ if (!document) throw new Error(`Document not found: ${documentId}`);
3141
+ if (!documentModelModule) throw new ModuleNotFoundError(documentType);
3142
+ if (document.header.documentType !== documentType) throw new DocumentTypeMismatchError(documentId, documentType, document.header.documentType);
3143
+ return [document, dispatch];
3103
3144
  }
3104
- /**
3105
- * Resolves a document model module by document type, mirroring the registry's
3106
- * semantics (`IDocumentModelRegistry.getModule`): with `version` omitted the
3107
- * LATEST version of the type wins (`version ?? 1` as each module's default),
3108
- * with `version` given only an exact match is returned. The reactor resolves
3109
- * modules the same way when a document is created, so metadata read through
3110
- * this hook and the version a creation actually uses cannot disagree.
3111
- */
3112
- function useDocumentModelModuleById(id, version) {
3113
- const documentModelModules = useDocumentModelModules();
3114
- if (!id || !documentModelModules) return void 0;
3115
- let latestModule;
3116
- let latestVersion = -1;
3117
- for (const module of documentModelModules) {
3118
- if (module.documentModel.global.id !== id) continue;
3119
- const moduleVersion = module.version ?? 1;
3120
- if (version !== void 0) {
3121
- if (moduleVersion === version) return module;
3122
- continue;
3123
- }
3124
- if (moduleVersion > latestVersion) {
3125
- latestVersion = moduleVersion;
3126
- latestModule = module;
3127
- }
3128
- }
3129
- return latestModule;
3145
+ /** Returns the selected document id */
3146
+ function useSelectedDocumentId() {
3147
+ const selectedNode = useSelectedNode();
3148
+ return selectedNode && isFileNode(selectedNode) ? selectedNode.id : void 0;
3149
+ }
3150
+ /** Returns the selected document. */
3151
+ function useSelectedDocumentSafe() {
3152
+ return useDocumentById(useSelectedDocumentId());
3153
+ }
3154
+ function useSelectedDocumentOfType(documentType) {
3155
+ const documentId = useSelectedDocumentId();
3156
+ if (!documentType) return [];
3157
+ if (!documentId) throw new NoSelectedDocumentError();
3158
+ return useDocumentOfType(documentId, documentType);
3130
3159
  }
3131
3160
  //#endregion
3132
3161
  //#region ../../node_modules/.pnpm/normalize-exception@4.0.1/node_modules/normalize-exception/build/src/descriptors.js
@@ -3884,16 +3913,6 @@ function useSetPHDocumentEditorConfig(config) {
3884
3913
  setIsInitialized(true);
3885
3914
  }, [config, isInitialized]);
3886
3915
  }
3887
- /** Returns a document of a specific type, throws an error if the found document has a different type */
3888
- function useDocumentOfType(documentId, documentType) {
3889
- const [document, dispatch] = useDocumentById(documentId);
3890
- const documentModelModule = useDocumentModelModuleById(documentType);
3891
- if (!documentId || !documentType) return [];
3892
- if (!document) throw new Error(`Document not found: ${documentId}`);
3893
- if (!documentModelModule) throw new ModuleNotFoundError(documentType);
3894
- if (document.header.documentType !== documentType) throw new DocumentTypeMismatchError(documentId, documentType, document.header.documentType);
3895
- return [document, dispatch];
3896
- }
3897
3916
  /**
3898
3917
  * Classifies a document's model version against the installed module
3899
3918
  * versions. Pure logic, extracted for testing.
@@ -4137,21 +4156,6 @@ function useNodeParentFolderById(id) {
4137
4156
  function useParentFolderForSelectedNode() {
4138
4157
  return useNodeParentFolderById(useSelectedNode()?.id);
4139
4158
  }
4140
- /** Returns the selected document id */
4141
- function useSelectedDocumentId() {
4142
- const selectedNode = useSelectedNode();
4143
- return selectedNode && isFileNode(selectedNode) ? selectedNode.id : void 0;
4144
- }
4145
- /** Returns the selected document. */
4146
- function useSelectedDocumentSafe() {
4147
- return useDocumentById(useSelectedDocumentId());
4148
- }
4149
- function useSelectedDocumentOfType(documentType) {
4150
- const documentId = useSelectedDocumentId();
4151
- if (!documentType) return [];
4152
- if (!documentId) throw new NoSelectedDocumentError();
4153
- return useDocumentOfType(documentId, documentType);
4154
- }
4155
4159
  const STORED_THEME_KEY = "ph:theme";
4156
4160
  const UPDATE_STORED_THEME = "ph:updateStoredTheme";
4157
4161
  const STORED_THEME_UPDATED = "ph:storedThemeUpdated";
@@ -4365,6 +4369,6 @@ function createDebouncedRefreshReactorDataClient(debounceDelayMs = DEFAULT_DEBOU
4365
4369
  createDebouncedRefreshReactorData();
4366
4370
  createDebouncedRefreshReactorDataClient();
4367
4371
  //#endregion
4368
- export { showRevisionHistory as A, t$2 as B, addFolder$1 as C, setSelectedNode as D, setSelectedDrive as E, useSelectedDriveId as F, useDocumentById as H, useSelectedDriveSafe as I, useStudioMode as L, useDragNode as M, useDropNode as N, showDeleteNodeModal as O, usePHToast as P, e$1 as R, addDocument as S, isFolderNodeKind as T, t$5 as V, useSelectedNodePath as _, useDownloadDocument as a, useTheme as b, useGetSwitchboardLink as c, useNodeParentFolderById as d, useNodesInSelectedDriveOrFolder as f, useSelectedFolder as g, useSelectedDocumentSafe as h, useDocumentVersionStatus as i, useDisabledEditors as j, showPHModal as k, useNodeActions as l, useSelectedDocumentOfType as m, preloadEditorModule as n, useEditorModules as o, useParentFolderForSelectedNode as p, useAllowedDocumentModelModules as r, useEditorModulesForDocumentType as s, getSyncStatusSync as t, useNodeById as u, useSetPHAppConfig as v, isFileNodeKind as w, useUserPermissions as x, useSetPHDocumentEditorConfig as y, e$4 as z };
4372
+ export { usePHToast as A, useSelectedDriveId as B, addFolder$1 as C, useDisabledEditors as D, showRevisionHistory as E, t$5 as F, useDocumentById as H, isFileNodeKind as I, isFolderNodeKind as L, e$1 as M, e$4 as N, useDragNode as O, t$2 as P, setSelectedDrive as R, addDocument as S, showPHModal as T, useSelectedDriveSafe as V, useSetPHDocumentEditorConfig as _, useDownloadDocument as a, useSelectedDocumentOfType as b, useGetSwitchboardLink as c, useNodeParentFolderById as d, useNodesInSelectedDriveOrFolder as f, useSetPHAppConfig as g, useSelectedNodePath as h, useDocumentVersionStatus as i, useStudioMode as j, useDropNode as k, useNodeActions as l, useSelectedFolder as m, preloadEditorModule as n, useEditorModules as o, useParentFolderForSelectedNode as p, useAllowedDocumentModelModules as r, useEditorModulesForDocumentType as s, getSyncStatusSync as t, useNodeById as u, useTheme as v, showDeleteNodeModal as w, useSelectedDocumentSafe as x, useUserPermissions as y, setSelectedNode as z };
4369
4373
 
4370
- //# sourceMappingURL=dist-n6WRzvGW.js.map
4374
+ //# sourceMappingURL=dist-Dq_xli8e.js.map