alinea 2.0.0-preview.12 → 2.0.0-preview.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.init/content/pages/welcome.json +1 -1
- package/dist/.mcp/later/dev.json +1 -1
- package/dist/.mcp/online/dev.json +1 -1
- package/dist/adapter/next/cms.js +16 -8
- package/dist/adapter/next/dashboardUrl.d.ts +6 -0
- package/dist/adapter/next/dashboardUrl.js +13 -0
- package/dist/adapter/next/syncCheck.d.ts +15 -2
- package/dist/adapter/next/syncCheck.js +26 -9
- package/dist/backend/Handler.js +5 -1
- package/dist/backend/api/BlobStore.d.ts +21 -0
- package/dist/backend/api/BlobStore.js +63 -0
- package/dist/backend/api/CreateBackend.js +10 -8
- package/dist/backend/api/DatabaseApi.d.ts +4 -1
- package/dist/backend/api/DatabaseApi.js +88 -4
- package/dist/backend/api/GithubApi.js +47 -24
- package/dist/backend/api/database.js +6 -6
- package/dist/bundled.d.ts +676 -280
- package/dist/chunks/{bun-sqlite-5SHXN3AT.js → bun-sqlite-RI6BYU5S.js} +3 -3
- package/dist/chunks/{chunk-OHGAVV4G.js → chunk-3QFSGTGF.js} +2 -3
- package/dist/chunks/{chunk-QJGGYF6E.js → chunk-4ZA6KZHS.js} +5 -5
- package/dist/chunks/{chunk-ASYKC6IE.js → chunk-5H4D5JQL.js} +1 -1
- package/dist/chunks/{chunk-ETWOY4AL.js → chunk-A2I6MCCS.js} +1 -1
- package/dist/chunks/{chunk-W5AXN7GH.js → chunk-CYVOGRSD.js} +1 -2
- package/dist/chunks/{chunk-TIJTT5ZI.js → chunk-G43W7AME.js} +1 -0
- package/dist/chunks/{chunk-RE523BQ7.js → chunk-HOETF6HN.js} +5829 -5830
- package/dist/chunks/{chunk-AIU6CMVT.js → chunk-PTYZMV5G.js} +1 -1
- package/dist/chunks/{chunk-JOF663EG.js → chunk-QHHMKJUO.js} +1 -1
- package/dist/chunks/{chunk-66YZ47TY.js → chunk-RAR44T5O.js} +1 -1
- package/dist/chunks/{chunk-QSN6RH6X.js → chunk-VA6NC3MI.js} +1 -1
- package/dist/chunks/{node-sqlite-XVNTNMCY.js → node-sqlite-C7VJ2NSN.js} +3 -3
- package/dist/cli/Mcp.js +1 -1
- package/dist/cli/Serve.js +1 -1
- package/dist/cli/bin.js +2 -3
- package/dist/cli/serve/mcp/DevMcp.js +1 -1
- package/dist/cli/serve/mcp/McpTools.js +29 -1
- package/dist/cloud/CloudRemote.js +1 -1
- package/dist/components/Alert.js +2 -2
- package/dist/components/AppShell.js +2 -2
- package/dist/components/Badge.d.ts +3 -1
- package/dist/components/Badge.js +5 -3
- package/dist/components/Breadcrumbs.js +7 -7
- package/dist/components/Button.d.ts +6 -1
- package/dist/components/Button.js +16 -7
- package/dist/components/Calendar.js +20 -20
- package/dist/components/Checkbox.js +7 -7
- package/dist/components/CheckboxGroup.js +4 -4
- package/dist/components/Code.js +2 -2
- package/dist/components/Collapsible.js +3 -3
- package/dist/components/ColorSwatch.js +2 -2
- package/dist/components/ColorSwatchPicker.js +2 -2
- package/dist/components/ComboBox.js +7 -7
- package/dist/components/Command.js +14 -13
- package/dist/components/ContentCard.d.ts +3 -1
- package/dist/components/ContentCard.js +46 -24
- package/dist/components/ContentGrid.js +17 -17
- package/dist/components/DataList.js +2 -2
- package/dist/components/DateField.js +2 -2
- package/dist/components/DatePicker.js +2 -2
- package/dist/components/DateRangePicker.js +2 -2
- package/dist/components/Dialog.js +7 -7
- package/dist/components/DropZone.js +6 -6
- package/dist/components/DropdownMenu.js +9 -9
- package/dist/components/Empty.js +5 -5
- package/dist/components/Field.js +8 -8
- package/dist/components/List.js +27 -27
- package/dist/components/MediaPreview.js +5 -5
- package/dist/components/MultipleSelect.js +22 -22
- package/dist/components/NavRail.js +4 -4
- package/dist/components/NumberField.js +4 -4
- package/dist/components/Page.js +3 -3
- package/dist/components/Popover.js +2 -2
- package/dist/components/PreviewFrame.js +9 -9
- package/dist/components/RadioGroup.js +9 -9
- package/dist/components/Resizable.js +4 -4
- package/dist/components/SearchField.d.ts +6 -1
- package/dist/components/SearchField.js +5 -3
- package/dist/components/Select.js +13 -13
- package/dist/components/Sheet.d.ts +50 -0
- package/dist/components/Sheet.js +202 -0
- package/dist/components/Sidebar.js +4 -4
- package/dist/components/SortableList.d.ts +34 -30
- package/dist/components/SortableList.js +161 -264
- package/dist/components/Spinner.js +2 -2
- package/dist/components/Surface.js +2 -2
- package/dist/components/Switch.js +8 -8
- package/dist/components/Table.d.ts +3 -1
- package/dist/components/Table.js +57 -46
- package/dist/components/Tabs.js +5 -5
- package/dist/components/TagGroup.js +8 -8
- package/dist/components/TextField.js +10 -10
- package/dist/components/TimeField.js +6 -6
- package/dist/components/Timestamp.js +1 -1
- package/dist/components/ToggleGroup.js +2 -2
- package/dist/components/Toolbar.js +2 -2
- package/dist/components/Tooltip.js +5 -5
- package/dist/components/Tree.js +24 -24
- package/dist/components/internal/DateControl.js +12 -12
- package/dist/components/internal/ListBoxOption.js +6 -6
- package/dist/components/internal/Locale.js +2 -2
- package/dist/components/internal/PopoverSurface.js +4 -4
- package/dist/components/internal/SelectionCheckbox.js +5 -5
- package/dist/components/internal/Slot.js +1 -1
- package/dist/components/internal/ToggleButton.js +3 -3
- package/dist/components/internal/Trigger.js +2 -2
- package/dist/components/internal/sortableDrag.d.ts +19 -0
- package/dist/components/internal/sortableDrag.js +175 -0
- package/dist/components/internal/useDragDrop.js +2 -2
- package/dist/components.d.ts +1 -0
- package/dist/components.js +1 -0
- package/dist/core/Config.d.ts +6 -1
- package/dist/core/Document.d.ts +9 -1
- package/dist/core/Document.js +31 -6
- package/dist/core/Overview.d.ts +2 -4
- package/dist/core/TextDoc.d.ts +4 -0
- package/dist/core/Validation.d.ts +0 -1
- package/dist/core/Validation.js +0 -6
- package/dist/core/field/RichTextField.js +23 -4
- package/dist/core/media/MediaTypes.js +1 -1
- package/dist/core/source/GithubSource.d.ts +4 -0
- package/dist/core/source/GithubSource.js +127 -25
- package/dist/core/source/GithubUsage.d.ts +21 -0
- package/dist/core/source/GithubUsage.js +47 -0
- package/dist/dashboard/App.d.ts +2 -2
- package/dist/dashboard/App.js +5 -3
- package/dist/dashboard/ViewKeys.d.ts +1 -0
- package/dist/dashboard/ViewKeys.js +1 -0
- package/dist/dashboard/app/ActivityStatus.js +7 -7
- package/dist/dashboard/app/AuthView.js +5 -5
- package/dist/dashboard/app/BlockSheet.d.ts +50 -0
- package/dist/dashboard/app/BlockSheet.js +207 -0
- package/dist/dashboard/app/BlockSheetStoryFrame.d.ts +6 -0
- package/dist/dashboard/app/BlockSheetStoryFrame.js +29 -0
- package/dist/dashboard/app/CompactField.js +16 -16
- package/dist/dashboard/app/DashboardLayout.js +3 -1
- package/dist/dashboard/app/EntryFields.js +2 -2
- package/dist/dashboard/app/EntryHeader.js +33 -34
- package/dist/dashboard/app/EntryReferences.js +7 -7
- package/dist/dashboard/app/EntrySidebar.js +15 -15
- package/dist/dashboard/app/EntrySidebarPreview.js +3 -3
- package/dist/dashboard/app/EntryStatusIcon.d.ts +23 -0
- package/dist/dashboard/app/EntryStatusIcon.js +58 -0
- package/dist/dashboard/app/EntryValidationModal.d.ts +6 -5
- package/dist/dashboard/app/EntryValidationModal.js +20 -20
- package/dist/dashboard/app/Explorer.d.ts +3 -1
- package/dist/dashboard/app/Explorer.js +48 -44
- package/dist/dashboard/app/ExplorerBatchActions.d.ts +3 -1
- package/dist/dashboard/app/ExplorerBatchActions.js +68 -43
- package/dist/dashboard/app/ExplorerCards.js +7 -1
- package/dist/dashboard/app/ExplorerControls.js +6 -6
- package/dist/dashboard/app/ExplorerList.js +5 -5
- package/dist/dashboard/app/ExplorerModal.js +2 -2
- package/dist/dashboard/app/ExplorerTable.js +11 -8
- package/dist/dashboard/app/ImageEditor.js +28 -28
- package/dist/dashboard/app/ImagePicker.js +3 -13
- package/dist/dashboard/app/LinkPicker.js +28 -26
- package/dist/dashboard/app/LocaleMenu.js +4 -4
- package/dist/dashboard/app/MediaPreviewCell.js +1 -1
- package/dist/dashboard/app/MoveConfirmDialog.d.ts +5 -0
- package/dist/dashboard/app/MoveConfirmDialog.js +79 -0
- package/dist/dashboard/app/OverviewCell.js +8 -13
- package/dist/dashboard/app/PendingUploadsView.js +3 -3
- package/dist/dashboard/app/ReadOnlyBadge.d.ts +1 -1
- package/dist/dashboard/app/RemoveDialog.d.ts +17 -0
- package/dist/dashboard/app/{DeleteDialog.js → RemoveDialog.js} +67 -27
- package/dist/dashboard/app/RemoveRedirect.d.ts +7 -0
- package/dist/dashboard/app/RemoveRedirect.js +123 -0
- package/dist/dashboard/app/SearchBar.d.ts +9 -0
- package/dist/dashboard/app/SearchBar.js +31 -0
- package/dist/dashboard/app/SidebarTree.js +27 -72
- package/dist/dashboard/app/WorkspaceMenu.js +7 -7
- package/dist/dashboard/app/WorkspaceRoots.js +12 -12
- package/dist/dashboard/app/editor/FileEditor.js +14 -14
- package/dist/dashboard/app/modals/CreateEntry.js +3 -3
- package/dist/dashboard/app/pages/EntryPage.d.ts +2 -1
- package/dist/dashboard/app/pages/EntryPage.js +34 -15
- package/dist/dashboard/app/pages/SplashPage.js +37 -37
- package/dist/dashboard/app/pages/UsersPage.js +12 -12
- package/dist/dashboard/app/ui/DashboardModal.js +15 -14
- package/dist/dashboard/atoms/dashboard.js +1 -1
- package/dist/dashboard/atoms/entry.js +1 -14
- package/dist/dashboard/atoms/entryTable.js +1 -0
- package/dist/dashboard/atoms/explorer.d.ts +4 -0
- package/dist/dashboard/atoms/explorer.js +19 -7
- package/dist/dashboard/atoms/graph.js +1 -1
- package/dist/dashboard/atoms/link.js +5 -2
- package/dist/dashboard/atoms/move.d.ts +5 -0
- package/dist/dashboard/atoms/move.js +29 -3
- package/dist/dashboard/atoms/moveConfirmation.d.ts +34 -0
- package/dist/dashboard/atoms/moveConfirmation.js +95 -0
- package/dist/dashboard/atoms/nav.d.ts +9 -5
- package/dist/dashboard/atoms/nav.js +120 -45
- package/dist/dashboard/atoms/overview.d.ts +6 -5
- package/dist/dashboard/atoms/overview.js +2 -16
- package/dist/dashboard/atoms/remove.d.ts +112 -0
- package/dist/dashboard/atoms/remove.js +268 -0
- package/dist/dashboard/atoms/root.d.ts +2 -2
- package/dist/dashboard/atoms/root.js +41 -26
- package/dist/dashboard/atoms/user.js +1 -1
- package/dist/dashboard/atoms/utils.js +1 -1
- package/dist/dashboard/boot/Boot.js +25 -17
- package/dist/dashboard/boot/DashboardWorker.d.ts +1 -0
- package/dist/dashboard/boot/DashboardWorker.js +10 -46
- package/dist/dashboard/boot/LoadWorker.js +17 -10
- package/dist/dashboard/cms/EntryTable.js +8 -5
- package/dist/database/BrowserEntryStore.d.ts +12 -62
- package/dist/database/BrowserEntryStore.js +97 -196
- package/dist/database/DatabaseTables.js +2 -2
- package/dist/database/EntryDatabase.js +21 -1
- package/dist/database/EntryTransaction.js +0 -35
- package/dist/database/EntryUrlAliases.d.ts +4 -0
- package/dist/database/EntryUrlAliases.js +16 -10
- package/dist/database/driver/RuntimeDatabase.js +3 -3
- package/dist/database/driver/WasmDatabase.d.ts +5 -18
- package/dist/database/driver/WasmDatabase.js +15 -16
- package/dist/database/entry/EntryTable.js +2 -2
- package/dist/database/query/EntryQuery.js +1 -1
- package/dist/database/query/Relation.js +1 -1
- package/dist/database/query/Search.js +2 -2
- package/dist/field/code/CodeField.view.js +16 -16
- package/dist/field/link/EntryLink.d.ts +4 -4
- package/dist/field/link/FileLink.d.ts +4 -4
- package/dist/field/link/ImageLink.d.ts +4 -4
- package/dist/field/link/Link.d.ts +1 -1
- package/dist/field/link/LinkField.d.ts +5 -0
- package/dist/field/link/LinkField.view.js +244 -370
- package/dist/field/link/UrlLink.d.ts +4 -4
- package/dist/field/list/ListField.d.ts +2 -0
- package/dist/field/list/ListField.view.d.ts +15 -0
- package/dist/field/list/ListField.view.js +343 -301
- package/dist/field/metadata/MetadataField.d.ts +17 -7
- package/dist/field/metadata/MetadataField.js +14 -3
- package/dist/field/metadata/MetadataField.view.d.ts +1 -0
- package/dist/field/metadata/MetadataField.view.js +25 -21
- package/dist/field/richtext/RichTextBlock.d.ts +3 -1
- package/dist/field/richtext/RichTextBlock.js +177 -74
- package/dist/field/richtext/RichTextBlockHost.js +1 -1
- package/dist/field/richtext/RichTextExtensions.js +31 -31
- package/dist/field/richtext/RichTextField.view.js +14 -8
- package/dist/field/richtext/RichTextInsertMenu.js +43 -27
- package/dist/field/views.js +2 -0
- package/dist/index.css +490 -309
- package/dist/picker/url/UrlPicker.js +1 -0
- package/docs/components/badge.md +1 -0
- package/docs/components/button.md +1 -0
- package/docs/components/content-card.md +1 -0
- package/docs/components/search-field.md +1 -0
- package/docs/components/sortable-list.md +5 -20
- package/docs/components/table.md +1 -0
- package/docs/configuration.md +1 -1
- package/docs/deploy/self-host.md +1 -1
- package/docs/deploy.md +5 -4
- package/docs/fields.md +1 -1
- package/docs/index.md +1 -1
- package/docs/instant-publishing.md +7 -22
- package/docs/overviews.md +3 -4
- package/docs/upgrading.md +3 -2
- package/llms-full.txt +31 -55
- package/package.json +2 -3
- package/dist/core/db/EntryValidationError.d.ts +0 -13
- package/dist/core/db/EntryValidationError.js +0 -23
- package/dist/dashboard/app/DeleteDialog.d.ts +0 -11
- package/dist/dashboard/atoms/delete.d.ts +0 -68
- package/dist/dashboard/atoms/delete.js +0 -143
- package/dist/chunks/{chunk-MOWR65LM.js → chunk-PYDOMKJZ.js} +71 -71
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { Config } from 'alinea/core/Config';
|
|
2
|
+
import type { EntryReference } from 'alinea/core/db/EntryReference';
|
|
3
|
+
import type { EntryFields } from 'alinea/core/EntryFields';
|
|
4
|
+
import type { Filter } from 'alinea/core/Filter';
|
|
5
|
+
import type { Policy } from 'alinea/core/Role';
|
|
6
|
+
import { type Atom, type PrimitiveAtom } from 'jotai';
|
|
7
|
+
import { type EntryReferenceWithSource } from './entry.js';
|
|
8
|
+
import type { ExplorerItemData, ExplorerLimitLocation } from './explorer.js';
|
|
9
|
+
/** Deleting removes the entries, archiving unpublishes them until restored */
|
|
10
|
+
export type RemoveAction = 'delete' | 'archive';
|
|
11
|
+
/** An entry that is about to be removed, in the locale it is shown in */
|
|
12
|
+
export interface RemoveSubject {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
type: string;
|
|
16
|
+
workspace: string;
|
|
17
|
+
root: string;
|
|
18
|
+
/** Null for entries without languages */
|
|
19
|
+
locale: string | null;
|
|
20
|
+
parents: Array<string>;
|
|
21
|
+
hasChildren: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** A translation that is removed, a null locale removes every version */
|
|
24
|
+
export interface Removal {
|
|
25
|
+
id: string;
|
|
26
|
+
locale: string | null;
|
|
27
|
+
}
|
|
28
|
+
/** An entry that is removed with the translation of its parent */
|
|
29
|
+
export interface RemovedDescendant extends Removal {
|
|
30
|
+
subjectId: string;
|
|
31
|
+
}
|
|
32
|
+
/** The public URL of a removed translation of a page */
|
|
33
|
+
export interface RemovedUrl extends Removal {
|
|
34
|
+
url: string;
|
|
35
|
+
}
|
|
36
|
+
/** The page the URLs of the removed pages redirect to */
|
|
37
|
+
export interface RedirectTarget {
|
|
38
|
+
id: string;
|
|
39
|
+
title: string;
|
|
40
|
+
url: string;
|
|
41
|
+
/** The languages of its versions, null for an entry without languages */
|
|
42
|
+
locales: Array<string | null>;
|
|
43
|
+
}
|
|
44
|
+
/** Which languages of the entries are removed and the links that will break */
|
|
45
|
+
export interface RemovePlan {
|
|
46
|
+
subjects: Array<RemoveSubject>;
|
|
47
|
+
/** The languages of a single entry the user can pick to delete, undefined
|
|
48
|
+
* for a batch */
|
|
49
|
+
locales?: Array<string>;
|
|
50
|
+
/** The picked languages, the shown language at first */
|
|
51
|
+
selectedLocales: PrimitiveAtom<Array<string>>;
|
|
52
|
+
removals: Atom<Array<Removal>>;
|
|
53
|
+
/** The versions linking to the removed translations and their contents,
|
|
54
|
+
* that are not removed themselves */
|
|
55
|
+
references: Atom<Array<EntryReferenceWithSource>>;
|
|
56
|
+
/** How many entries the user can not read link to them, their titles stay
|
|
57
|
+
* hidden */
|
|
58
|
+
hiddenSources: Atom<number>;
|
|
59
|
+
/** Every removed translation is published and can be archived instead */
|
|
60
|
+
archivable: Atom<boolean>;
|
|
61
|
+
/** The public URLs of the removed translations of pages */
|
|
62
|
+
urls: Atom<Array<RemovedUrl>>;
|
|
63
|
+
/** The page the editor picked to redirect the URLs to */
|
|
64
|
+
redirect: PrimitiveAtom<RedirectTarget | undefined>;
|
|
65
|
+
/** The URLs the redirect target has no version for, they don't redirect */
|
|
66
|
+
unredirected: Atom<Array<RemovedUrl>>;
|
|
67
|
+
}
|
|
68
|
+
export interface RemovePlanOptions {
|
|
69
|
+
subjects: Array<RemoveSubject>;
|
|
70
|
+
locales?: Array<string>;
|
|
71
|
+
references?: Array<EntryReferenceWithSource>;
|
|
72
|
+
/** Links from versions the user can not read */
|
|
73
|
+
hidden?: Array<EntryReference>;
|
|
74
|
+
descendants?: Array<RemovedDescendant>;
|
|
75
|
+
/** The translations that can be archived */
|
|
76
|
+
archivable?: Array<Removal>;
|
|
77
|
+
/** The public URLs of the subjects, in each of their languages */
|
|
78
|
+
urls?: Array<RemovedUrl>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Entries without languages are removed entirely, the others in the picked
|
|
82
|
+
* languages or, in a batch, the language they are shown in.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createRemovePlan({ subjects, locales, references, hidden, descendants, archivable, urls }: RemovePlanOptions): RemovePlan;
|
|
85
|
+
export interface RedirectPicker {
|
|
86
|
+
/** The entries of the types that hold URL aliases */
|
|
87
|
+
condition: Filter<EntryFields>;
|
|
88
|
+
/** The roots of the workspace of the removed entries */
|
|
89
|
+
locations: Array<ExplorerLimitLocation>;
|
|
90
|
+
/** Entries that are not removed and the user may add an alias to */
|
|
91
|
+
canSelect(item: ExplorerItemData): boolean;
|
|
92
|
+
}
|
|
93
|
+
/** Which pages the URLs of the removed entries can redirect to */
|
|
94
|
+
export declare function redirectPicker(config: Config, policy: Policy, subjects: Array<RemoveSubject>): RedirectPicker;
|
|
95
|
+
/** Loads the page the editor picked to redirect the URLs to */
|
|
96
|
+
export declare const loadRedirectTargetAtom: import("jotai").WritableAtom<null, [id: string, locale: string | null], Promise<RedirectTarget | undefined>> & {
|
|
97
|
+
init: null;
|
|
98
|
+
};
|
|
99
|
+
/** Loads the references to the entries before the remove dialog opens */
|
|
100
|
+
export declare const loadRemovePlanAtom: import("jotai").WritableAtom<null, [subjects: RemoveSubject[], locales?: string[] | undefined], Promise<RemovePlan>> & {
|
|
101
|
+
init: null;
|
|
102
|
+
};
|
|
103
|
+
/** Removes the translations and redirects their URLs in one commit */
|
|
104
|
+
export declare const deleteEntriesAtom: import("jotai").WritableAtom<null, [plan: RemovePlan], Promise<void>> & {
|
|
105
|
+
init: null;
|
|
106
|
+
};
|
|
107
|
+
/** Archives the translations the plan would delete */
|
|
108
|
+
export declare const archiveEntriesAtom: import("jotai").WritableAtom<null, [plan: RemovePlan], Promise<void>> & {
|
|
109
|
+
init: null;
|
|
110
|
+
};
|
|
111
|
+
/** Archive without asking first, until the browser session ends */
|
|
112
|
+
export declare const archiveDirectlyAtom: import("jotai").WritableAtom<boolean, [boolean | typeof import("jotai/utils").RESET | ((prev: boolean) => boolean | typeof import("jotai/utils").RESET)], void>;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
atomWithStorage,
|
|
3
|
+
createJSONStorage
|
|
4
|
+
} from "../../chunks/chunk-G43W7AME.js";
|
|
5
|
+
import {
|
|
6
|
+
atom
|
|
7
|
+
} from "../../chunks/chunk-CFNRVI3Y.js";
|
|
8
|
+
import "../../chunks/chunk-CQ52GEHY.js";
|
|
9
|
+
|
|
10
|
+
// src/dashboard/atoms/remove.ts
|
|
11
|
+
import { Entry } from "alinea/core/Entry";
|
|
12
|
+
import { getWorkspace } from "alinea/core/Internal";
|
|
13
|
+
import { MediaFile, MediaLibrary } from "alinea/core/media/MediaTypes";
|
|
14
|
+
import { Root } from "alinea/core/Root";
|
|
15
|
+
import { entries } from "alinea/core/util/Objects";
|
|
16
|
+
import { dataWithUrlAliases, hasUrlAliases } from "alinea/database/EntryUrlAliases";
|
|
17
|
+
import { configAtom, graphAtom } from "./core.js";
|
|
18
|
+
import { loadIncomingReferences } from "./entry.js";
|
|
19
|
+
import { policyAtom } from "./user.js";
|
|
20
|
+
function createRemovePlan({
|
|
21
|
+
subjects,
|
|
22
|
+
locales,
|
|
23
|
+
references = [],
|
|
24
|
+
hidden = [],
|
|
25
|
+
descendants = [],
|
|
26
|
+
archivable = [],
|
|
27
|
+
urls = []
|
|
28
|
+
}) {
|
|
29
|
+
const shown = subjects[0]?.locale;
|
|
30
|
+
const selectedLocales = atom(
|
|
31
|
+
shown && locales?.includes(shown) ? [shown] : Array()
|
|
32
|
+
);
|
|
33
|
+
const removals = atom((get) => {
|
|
34
|
+
const selected = get(selectedLocales);
|
|
35
|
+
return subjects.flatMap(({ id, locale }) => {
|
|
36
|
+
if (locale === null || !locales) return [{ id, locale }];
|
|
37
|
+
return selected.map((locale2) => ({ id, locale: locale2 }));
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
const removed = atom(
|
|
41
|
+
(get) => get(removals).flatMap((removal) => [
|
|
42
|
+
removal,
|
|
43
|
+
...descendants.filter(
|
|
44
|
+
({ subjectId, locale }) => subjectId === removal.id && locale === removal.locale
|
|
45
|
+
)
|
|
46
|
+
])
|
|
47
|
+
);
|
|
48
|
+
const breaks = (reference, removed2) => !removed2.some(
|
|
49
|
+
({ id, locale }) => id === reference.sourceId && locale === reference.sourceLocale
|
|
50
|
+
) && // References hold the language of the linking entry: links from an
|
|
51
|
+
// entry without languages can point to any language
|
|
52
|
+
removed2.some(
|
|
53
|
+
({ id, locale }) => id === reference.targetId && (locale === null || reference.sourceLocale === null || locale === reference.sourceLocale)
|
|
54
|
+
);
|
|
55
|
+
const removedUrls = atom(
|
|
56
|
+
(get) => get(removals).flatMap(
|
|
57
|
+
({ id, locale }) => urls.filter((url) => url.id === id && url.locale === locale)
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
const redirect = atom(void 0);
|
|
61
|
+
return {
|
|
62
|
+
subjects,
|
|
63
|
+
locales,
|
|
64
|
+
selectedLocales,
|
|
65
|
+
removals,
|
|
66
|
+
references: atom((get) => {
|
|
67
|
+
const current = get(removed);
|
|
68
|
+
return references.filter(({ reference }) => breaks(reference, current));
|
|
69
|
+
}),
|
|
70
|
+
hiddenSources: atom((get) => {
|
|
71
|
+
const current = get(removed);
|
|
72
|
+
const sources = hidden.filter((reference) => breaks(reference, current)).map((reference) => reference.sourceId);
|
|
73
|
+
return new Set(sources).size;
|
|
74
|
+
}),
|
|
75
|
+
archivable: atom((get) => {
|
|
76
|
+
const current = get(removals);
|
|
77
|
+
return current.length > 0 && current.every(
|
|
78
|
+
({ id, locale }) => archivable.some((item) => item.id === id && item.locale === locale)
|
|
79
|
+
);
|
|
80
|
+
}),
|
|
81
|
+
urls: removedUrls,
|
|
82
|
+
redirect,
|
|
83
|
+
unredirected: atom((get) => {
|
|
84
|
+
const target = get(redirect);
|
|
85
|
+
if (!target) return [];
|
|
86
|
+
return get(removedUrls).filter(
|
|
87
|
+
(url) => redirectLocale(target.locales, url.locale) === void 0
|
|
88
|
+
);
|
|
89
|
+
})
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function redirectLocale(locales, locale) {
|
|
93
|
+
if (locales.includes(locale)) return locale;
|
|
94
|
+
if (locales.includes(null)) return null;
|
|
95
|
+
return void 0;
|
|
96
|
+
}
|
|
97
|
+
function hasUrl(type) {
|
|
98
|
+
if (!type || type === MediaFile || type === MediaLibrary) return false;
|
|
99
|
+
return hasUrlAliases(type);
|
|
100
|
+
}
|
|
101
|
+
var redirectStatuses = ["published", "draft"];
|
|
102
|
+
function redirectPicker(config, policy, subjects) {
|
|
103
|
+
const [first] = subjects;
|
|
104
|
+
const removed = new Set(subjects.map((subject) => subject.id));
|
|
105
|
+
const types = entries(config.schema).filter(([, type]) => hasUrl(type)).map(([name]) => name);
|
|
106
|
+
const workspace = first && config.workspaces[first.workspace];
|
|
107
|
+
const roots = workspace ? entries(getWorkspace(workspace).roots) : [];
|
|
108
|
+
const locations = roots.filter(([, root]) => !Root.isMediaRoot(root)).map(([root]) => ({ workspace: first.workspace, root }));
|
|
109
|
+
return {
|
|
110
|
+
condition: { _type: { in: types } },
|
|
111
|
+
locations,
|
|
112
|
+
canSelect(item) {
|
|
113
|
+
if (removed.has(item.id)) return false;
|
|
114
|
+
if (item.parents.some((parent) => removed.has(parent))) return false;
|
|
115
|
+
return policy.canUpdate({ ...item, field: "metadata.aliases" }) && policy.canPublish(item);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
var loadRedirectTargetAtom = atom(
|
|
120
|
+
null,
|
|
121
|
+
async (get, _set, id, locale) => {
|
|
122
|
+
const versions = await get(graphAtom).find({
|
|
123
|
+
id,
|
|
124
|
+
status: "all",
|
|
125
|
+
versionStatus: { in: redirectStatuses },
|
|
126
|
+
select: { title: Entry.title, locale: Entry.locale, url: Entry.url }
|
|
127
|
+
});
|
|
128
|
+
const shown = versions.find((version) => version.locale === locale) ?? versions[0];
|
|
129
|
+
if (!shown) return void 0;
|
|
130
|
+
const locales = new Set(versions.map((version) => version.locale));
|
|
131
|
+
return { id, title: shown.title, url: shown.url, locales: [...locales] };
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
var loadRemovePlanAtom = atom(
|
|
135
|
+
null,
|
|
136
|
+
async (get, _set, subjects, locales) => {
|
|
137
|
+
const config = get(configAtom);
|
|
138
|
+
const policy = get(policyAtom);
|
|
139
|
+
const [first] = subjects;
|
|
140
|
+
const versions = await get(graphAtom).find({
|
|
141
|
+
id: { in: subjects.map((subject) => subject.id) },
|
|
142
|
+
status: "all",
|
|
143
|
+
select: {
|
|
144
|
+
id: Entry.id,
|
|
145
|
+
locale: Entry.locale,
|
|
146
|
+
status: Entry.status,
|
|
147
|
+
active: Entry.active,
|
|
148
|
+
url: Entry.url,
|
|
149
|
+
descendants: {
|
|
150
|
+
edge: "children",
|
|
151
|
+
// The deepest level queried, queries are sent as JSON
|
|
152
|
+
depth: 999,
|
|
153
|
+
status: "all",
|
|
154
|
+
select: Entry.id
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
const descendants = versions.flatMap(
|
|
159
|
+
(version) => version.descendants.map((id) => ({
|
|
160
|
+
id,
|
|
161
|
+
locale: version.locale,
|
|
162
|
+
subjectId: version.id
|
|
163
|
+
}))
|
|
164
|
+
);
|
|
165
|
+
const subjectOf = (id) => subjects.find((subject) => subject.id === id);
|
|
166
|
+
const archivable = versions.flatMap(({ id, locale, status, active }) => {
|
|
167
|
+
const subject = subjectOf(id);
|
|
168
|
+
if (!subject || !active || status !== "published") return [];
|
|
169
|
+
if (config.schema[subject.type] === MediaFile) return [];
|
|
170
|
+
if (!policy.canArchive({ ...subject, locale })) return [];
|
|
171
|
+
return [{ id, locale }];
|
|
172
|
+
});
|
|
173
|
+
const urls = versions.flatMap(({ id, locale, status, url }) => {
|
|
174
|
+
const subject = subjectOf(id);
|
|
175
|
+
if (!subject || status !== "published" || !url) return [];
|
|
176
|
+
if (!hasUrl(config.schema[subject.type])) return [];
|
|
177
|
+
return [{ id, locale, url }];
|
|
178
|
+
});
|
|
179
|
+
const targetIds = new Set(
|
|
180
|
+
subjects.map((subject) => subject.id).concat(descendants.map((d) => d.id))
|
|
181
|
+
);
|
|
182
|
+
const { references, hidden } = await loadIncomingReferences(
|
|
183
|
+
get,
|
|
184
|
+
Array.from(targetIds)
|
|
185
|
+
);
|
|
186
|
+
return createRemovePlan({
|
|
187
|
+
subjects,
|
|
188
|
+
locales: locales?.filter((locale) => policy.canDelete({ ...first, locale })),
|
|
189
|
+
references,
|
|
190
|
+
hidden,
|
|
191
|
+
descendants,
|
|
192
|
+
archivable,
|
|
193
|
+
urls: urls.filter(
|
|
194
|
+
(url, index) => urls.findIndex(
|
|
195
|
+
(other) => other.id === url.id && other.locale === url.locale
|
|
196
|
+
) === index
|
|
197
|
+
)
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
async function redirects(get, plan) {
|
|
202
|
+
const target = get(plan.redirect);
|
|
203
|
+
const urls = get(plan.urls);
|
|
204
|
+
if (!target || urls.length === 0) return [];
|
|
205
|
+
const versions = await get(graphAtom).find({
|
|
206
|
+
id: target.id,
|
|
207
|
+
status: "all",
|
|
208
|
+
versionStatus: { in: redirectStatuses },
|
|
209
|
+
select: {
|
|
210
|
+
locale: Entry.locale,
|
|
211
|
+
status: Entry.versionStatus,
|
|
212
|
+
data: Entry.data
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
const locales = versions.map((version) => version.locale);
|
|
216
|
+
return versions.flatMap(({ locale, status, data }) => {
|
|
217
|
+
const redirected = urls.filter((url) => redirectLocale(locales, url.locale) === locale).map((url) => url.url);
|
|
218
|
+
const next = dataWithUrlAliases(data, redirected);
|
|
219
|
+
if (next === data) return [];
|
|
220
|
+
const set = { metadata: next.metadata };
|
|
221
|
+
return [{ op: "update", id: target.id, locale, status, set }];
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
var deleteEntriesAtom = atom(
|
|
225
|
+
null,
|
|
226
|
+
async (get, _set, plan) => {
|
|
227
|
+
const removals = get(plan.removals).map(
|
|
228
|
+
(removal) => ({ op: "remove", ...removal })
|
|
229
|
+
);
|
|
230
|
+
const updates = await redirects(get, plan);
|
|
231
|
+
await get(graphAtom).mutate(removals.concat(updates));
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
var archiveEntriesAtom = atom(
|
|
235
|
+
null,
|
|
236
|
+
async (get, _set, plan) => {
|
|
237
|
+
const removals = get(plan.removals).map(
|
|
238
|
+
(removal) => ({ op: "archive", ...removal })
|
|
239
|
+
);
|
|
240
|
+
const updates = await redirects(get, plan);
|
|
241
|
+
await get(graphAtom).mutate(removals.concat(updates));
|
|
242
|
+
}
|
|
243
|
+
);
|
|
244
|
+
var noStorage = { getItem: () => null, setItem() {
|
|
245
|
+
}, removeItem() {
|
|
246
|
+
} };
|
|
247
|
+
function session() {
|
|
248
|
+
try {
|
|
249
|
+
return globalThis.sessionStorage ?? noStorage;
|
|
250
|
+
} catch {
|
|
251
|
+
return noStorage;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
var archiveDirectlyAtom = atomWithStorage(
|
|
255
|
+
"alinea-dashboard-archive-directly",
|
|
256
|
+
false,
|
|
257
|
+
createJSONStorage(session),
|
|
258
|
+
{ getOnInit: true }
|
|
259
|
+
);
|
|
260
|
+
export {
|
|
261
|
+
archiveDirectlyAtom,
|
|
262
|
+
archiveEntriesAtom,
|
|
263
|
+
createRemovePlan,
|
|
264
|
+
deleteEntriesAtom,
|
|
265
|
+
loadRedirectTargetAtom,
|
|
266
|
+
loadRemovePlanAtom,
|
|
267
|
+
redirectPicker
|
|
268
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Config } from 'alinea/core/Config';
|
|
1
2
|
import type { EntryStatus } from 'alinea/core/Entry';
|
|
2
3
|
import { Permission } from 'alinea/core/Role';
|
|
3
4
|
import { type RootData, type RootI18n } from 'alinea/core/Root';
|
|
4
|
-
import { Schema } from 'alinea/core/Schema';
|
|
5
5
|
import { ExplorerAtoms } from 'alinea/dashboard/atoms/explorer';
|
|
6
6
|
import { type Atom, type PrimitiveAtom } from 'jotai';
|
|
7
7
|
import type { ComponentType } from 'react';
|
|
@@ -113,7 +113,7 @@ export declare const rootAtoms: (workspace: string, root: string) => RootAtoms;
|
|
|
113
113
|
* Entries can be dropped on a container, but only placed before or after the
|
|
114
114
|
* children of a parent that does not order them, and never inside themselves
|
|
115
115
|
*/
|
|
116
|
-
export declare function treeAcceptsDrop(
|
|
116
|
+
export declare function treeAcceptsDrop(config: Config, rootData: RootData, entries: Map<string, RootTreeItem>, target: DropTarget, keys?: ReadonlySet<Key>): boolean;
|
|
117
117
|
/** The selected entry, or the location of a selected entry that is not listed */
|
|
118
118
|
export declare function locatedItem({ entries, snapshot }: TreeView): RootTreeItem | undefined;
|
|
119
119
|
export {};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
selectAtom,
|
|
3
3
|
unwrap
|
|
4
|
-
} from "../../chunks/chunk-
|
|
4
|
+
} from "../../chunks/chunk-G43W7AME.js";
|
|
5
5
|
import {
|
|
6
6
|
atom
|
|
7
7
|
} from "../../chunks/chunk-CFNRVI3Y.js";
|
|
8
8
|
import "../../chunks/chunk-CQ52GEHY.js";
|
|
9
9
|
|
|
10
10
|
// src/dashboard/atoms/root.ts
|
|
11
|
+
import { Config } from "alinea/core/Config";
|
|
11
12
|
import { Permission } from "alinea/core/Role";
|
|
12
13
|
import { Root } from "alinea/core/Root";
|
|
13
14
|
import { Schema } from "alinea/core/Schema";
|
|
@@ -18,6 +19,8 @@ import {
|
|
|
18
19
|
} from "alinea/dashboard/atoms/explorer";
|
|
19
20
|
import { IcOutlineDescription } from "../icons.js";
|
|
20
21
|
import { viewAtoms } from "./config.js";
|
|
22
|
+
import { confirmMoveAtom, draggedEntriesAtom } from "./moveConfirmation.js";
|
|
23
|
+
import { rootAcceptsType } from "./move.js";
|
|
21
24
|
import { configAtom, graphAtom } from "./core.js";
|
|
22
25
|
import {
|
|
23
26
|
loadTreeChildren,
|
|
@@ -381,11 +384,6 @@ var RootAtoms = class {
|
|
|
381
384
|
* scroll offset when the editor returns to it through either of them.
|
|
382
385
|
*/
|
|
383
386
|
explorerScrollOffset = dispense((_key) => atom(0));
|
|
384
|
-
/**
|
|
385
|
-
* The filters picked in the explorers of this root, kept while the editor
|
|
386
|
-
* opens entries and folders. Each overview applies the ones it declares.
|
|
387
|
-
*/
|
|
388
|
-
#explorerFilters = atom({});
|
|
389
387
|
children = dispense((parentId) => {
|
|
390
388
|
const location = {
|
|
391
389
|
workspace: this.workspace,
|
|
@@ -412,7 +410,9 @@ var RootAtoms = class {
|
|
|
412
410
|
enableNavigation: true,
|
|
413
411
|
sortState: overviewSortAtom(this.workspace, this.key, parentId),
|
|
414
412
|
rootData: this.data,
|
|
415
|
-
|
|
413
|
+
// The filters picked in this list, kept when the editor comes back to
|
|
414
|
+
// it, like its sort, but not applied to the lists of other entries
|
|
415
|
+
filterState: atom({}),
|
|
416
416
|
scrollOffset: this.explorerScrollOffset,
|
|
417
417
|
selectedLocaleAtom: this.#explorerLocale,
|
|
418
418
|
selectionBehavior: "toggle",
|
|
@@ -443,7 +443,8 @@ var RootAtoms = class {
|
|
|
443
443
|
acceptedDragTypes = [...dashboardEntryDragTypes];
|
|
444
444
|
getItems = atom(
|
|
445
445
|
null,
|
|
446
|
-
(_get,
|
|
446
|
+
(_get, set, keys) => {
|
|
447
|
+
set(draggedEntriesAtom, keys);
|
|
447
448
|
return [...keys].map(dashboardEntryDragItem);
|
|
448
449
|
}
|
|
449
450
|
);
|
|
@@ -454,12 +455,18 @@ var RootAtoms = class {
|
|
|
454
455
|
});
|
|
455
456
|
onMove = atom(
|
|
456
457
|
null,
|
|
457
|
-
async (get,
|
|
458
|
+
async (get, set, event, tree) => {
|
|
458
459
|
const policy = get(policyAtom);
|
|
459
460
|
const permission = event.target.position === "on" ? Permission.Move : Permission.Reorder;
|
|
460
|
-
const { schema } = get(configAtom);
|
|
461
461
|
const { entries } = get(tree.view);
|
|
462
|
-
|
|
462
|
+
const accepted = treeAcceptsDrop(
|
|
463
|
+
get(configAtom),
|
|
464
|
+
get(this.data),
|
|
465
|
+
entries,
|
|
466
|
+
event.target,
|
|
467
|
+
event.keys
|
|
468
|
+
);
|
|
469
|
+
if (!accepted) return;
|
|
463
470
|
const moving = get(tree.items).filter((item) => event.keys.has(item.id));
|
|
464
471
|
for (const item of moving)
|
|
465
472
|
policy.assert(permission, {
|
|
@@ -470,30 +477,38 @@ var RootAtoms = class {
|
|
|
470
477
|
locale: item.locale,
|
|
471
478
|
parents: item.parents
|
|
472
479
|
});
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
event.target
|
|
477
|
-
);
|
|
480
|
+
const ids = moving.map((item) => item.id);
|
|
481
|
+
if (!await set(confirmMoveAtom, ids, event.target)) return;
|
|
482
|
+
await moveEntries(get(graphAtom), ids, event.target);
|
|
478
483
|
}
|
|
479
484
|
);
|
|
480
|
-
onDrop = atom(null, async (get,
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
event.target
|
|
485
|
-
);
|
|
485
|
+
onDrop = atom(null, async (get, set, event) => {
|
|
486
|
+
const ids = dashboardEntryDropIds(event.items);
|
|
487
|
+
if (!await set(confirmMoveAtom, ids, event.target)) return;
|
|
488
|
+
await moveEntries(get(graphAtom), ids, event.target);
|
|
486
489
|
});
|
|
487
490
|
};
|
|
488
491
|
var rootAtoms = dispense(
|
|
489
492
|
(workspace, root) => new RootAtoms(workspace, root)
|
|
490
493
|
);
|
|
491
|
-
function treeAcceptsDrop(
|
|
494
|
+
function treeAcceptsDrop(config, rootData, entries, target, keys = /* @__PURE__ */ new Set()) {
|
|
492
495
|
const entry = entries.get(String(target.key));
|
|
493
496
|
if (!entry || entry.parents.some((id) => keys.has(id))) return false;
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
+
const into = target.position === "on";
|
|
498
|
+
if (into ? keys.has(entry.id) : entry.ordered) return false;
|
|
499
|
+
const parentId = into ? entry.id : entry.parentId;
|
|
500
|
+
const parent = parentId ? entries.get(parentId) : void 0;
|
|
501
|
+
const parentType = parent && config.schema[parent.type];
|
|
502
|
+
if (into && !(parentType && Type.isContainer(parentType))) return false;
|
|
503
|
+
for (const key of keys) {
|
|
504
|
+
const dragged = entries.get(String(key));
|
|
505
|
+
if (!dragged || !config.schema[dragged.type]) continue;
|
|
506
|
+
if (dragged.parentId === parentId) continue;
|
|
507
|
+
if (parentId && !parentType) continue;
|
|
508
|
+
const accepted = parentType ? Config.typeContains(config, parentType, config.schema[dragged.type]) : rootAcceptsType(config, rootData, dragged.type);
|
|
509
|
+
if (!accepted) return false;
|
|
510
|
+
}
|
|
511
|
+
return true;
|
|
497
512
|
}
|
|
498
513
|
function locatedItem({
|
|
499
514
|
entries,
|
|
@@ -5,7 +5,6 @@ import "../../chunks/chunk-CQ52GEHY.js";
|
|
|
5
5
|
|
|
6
6
|
// src/dashboard/boot/Boot.tsx
|
|
7
7
|
import { IndexEvent } from "alinea/core/db/IndexEvent";
|
|
8
|
-
import { MemorySource } from "alinea/core/source/MemorySource";
|
|
9
8
|
import { createRoot } from "react-dom/client";
|
|
10
9
|
import { App } from "../App.js";
|
|
11
10
|
import { ActivityEvent } from "./ActivityEvent.js";
|
|
@@ -18,15 +17,7 @@ async function boot(gen) {
|
|
|
18
17
|
if (inWorker) {
|
|
19
18
|
loadWorker(gen);
|
|
20
19
|
} else {
|
|
21
|
-
|
|
22
|
-
let worker;
|
|
23
|
-
try {
|
|
24
|
-
;
|
|
25
|
-
[events, worker] = createSharedWorker();
|
|
26
|
-
} catch {
|
|
27
|
-
console.warn("Shared worker not supported, falling back to local worker.");
|
|
28
|
-
events = worker = new DashboardWorker(new MemorySource());
|
|
29
|
-
}
|
|
20
|
+
const [events, worker] = connect();
|
|
30
21
|
const scripts = document.getElementsByTagName("script");
|
|
31
22
|
const element = scripts[scripts.length - 1];
|
|
32
23
|
const into = document.createElement("div");
|
|
@@ -56,20 +47,37 @@ async function boot(gen) {
|
|
|
56
47
|
}
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
|
-
function
|
|
50
|
+
function connect() {
|
|
51
|
+
const options = { type: "module", name: "Alinea dashboard" };
|
|
52
|
+
try {
|
|
53
|
+
const worker = new SharedWorker(import.meta.url, options);
|
|
54
|
+
return [listen(worker.port), wrap2(worker.port)];
|
|
55
|
+
} catch {
|
|
56
|
+
console.warn("Shared worker not supported, falling back to a worker.");
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const worker = new Worker(import.meta.url, options);
|
|
60
|
+
return [listen(worker), wrap2(worker)];
|
|
61
|
+
} catch {
|
|
62
|
+
console.warn("Worker not supported, running on the main thread.");
|
|
63
|
+
const worker = new DashboardWorker();
|
|
64
|
+
return [worker, worker];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function wrap2(endpoint) {
|
|
68
|
+
return wrap(endpoint);
|
|
69
|
+
}
|
|
70
|
+
function listen(source) {
|
|
60
71
|
const events = new EventTarget();
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
name: "Alinea dashboard"
|
|
64
|
-
});
|
|
65
|
-
worker.port.addEventListener("message", ({ data }) => {
|
|
72
|
+
source.addEventListener("message", (event) => {
|
|
73
|
+
const { data } = event;
|
|
66
74
|
if (data.type === IndexEvent.type) {
|
|
67
75
|
events.dispatchEvent(new IndexEvent(data.data));
|
|
68
76
|
} else if (data.type === ActivityEvent.type) {
|
|
69
77
|
events.dispatchEvent(new ActivityEvent(data.activities));
|
|
70
78
|
}
|
|
71
79
|
});
|
|
72
|
-
return
|
|
80
|
+
return events;
|
|
73
81
|
}
|
|
74
82
|
function isWorkerScope() {
|
|
75
83
|
return typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
|
|
@@ -7,6 +7,7 @@ import { EntryStore } from 'alinea/database/EntryStore';
|
|
|
7
7
|
import { type Activity } from './ActivityEvent.js';
|
|
8
8
|
export declare class DashboardWorker extends EventTarget {
|
|
9
9
|
#private;
|
|
10
|
+
/** Keep the content in memory with `source`, instead of in the browser. */
|
|
10
11
|
constructor(source?: Source);
|
|
11
12
|
get db(): EntryStore | Promise<EntryStore>;
|
|
12
13
|
sync(): Promise<string>;
|