@abraca/nuxt 2.0.11 → 2.3.0
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/module.d.mts +68 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +99 -4
- package/dist/runtime/components/ACodeEditor.d.vue.ts +26 -0
- package/dist/runtime/components/ACodeEditor.vue +268 -0
- package/dist/runtime/components/ACodeEditor.vue.d.ts +26 -0
- package/dist/runtime/components/ADocumentTree.vue +52 -20
- package/dist/runtime/components/AEditor.d.vue.ts +20 -13
- package/dist/runtime/components/AEditor.vue +55 -2
- package/dist/runtime/components/AEditor.vue.d.ts +20 -13
- package/dist/runtime/components/ANodePanel.vue +64 -60
- package/dist/runtime/components/ANotificationBell.d.vue.ts +1 -1
- package/dist/runtime/components/ANotificationBell.vue.d.ts +1 -1
- package/dist/runtime/components/ASpaceFormModal.d.vue.ts +2 -2
- package/dist/runtime/components/ASpaceFormModal.vue.d.ts +2 -2
- package/dist/runtime/components/aware/AMedia.d.vue.ts +1 -1
- package/dist/runtime/components/aware/AMedia.vue.d.ts +1 -1
- package/dist/runtime/components/aware/APresenceBlobs.d.vue.ts +29 -1
- package/dist/runtime/components/aware/APresenceBlobs.vue +54 -8
- package/dist/runtime/components/aware/APresenceBlobs.vue.d.ts +29 -1
- package/dist/runtime/components/aware/APresenceCursors.d.vue.ts +11 -0
- package/dist/runtime/components/aware/APresenceCursors.vue +74 -9
- package/dist/runtime/components/aware/APresenceCursors.vue.d.ts +11 -0
- package/dist/runtime/components/aware/AToggleGroup.d.vue.ts +28 -13
- package/dist/runtime/components/aware/AToggleGroup.vue +56 -20
- package/dist/runtime/components/aware/AToggleGroup.vue.d.ts +28 -13
- package/dist/runtime/components/docs/ADocsNavigation.d.vue.ts +1 -1
- package/dist/runtime/components/docs/ADocsNavigation.vue.d.ts +1 -1
- package/dist/runtime/components/docs/ADocsSearch.d.vue.ts +1 -1
- package/dist/runtime/components/docs/ADocsSearch.vue.d.ts +1 -1
- package/dist/runtime/components/docs/ADocsSearchButton.d.vue.ts +1 -1
- package/dist/runtime/components/docs/ADocsSearchButton.vue.d.ts +1 -1
- package/dist/runtime/components/docs/ADocsToc.d.vue.ts +2 -2
- package/dist/runtime/components/docs/ADocsToc.vue.d.ts +2 -2
- package/dist/runtime/components/editor/AEditorRedoButton.d.vue.ts +1 -1
- package/dist/runtime/components/editor/AEditorRedoButton.vue.d.ts +1 -1
- package/dist/runtime/components/editor/AEditorUndoButton.d.vue.ts +1 -1
- package/dist/runtime/components/editor/AEditorUndoButton.vue.d.ts +1 -1
- package/dist/runtime/components/editor/ANodeInlineLabel.d.vue.ts +1 -1
- package/dist/runtime/components/editor/ANodeInlineLabel.vue.d.ts +1 -1
- package/dist/runtime/components/registry/APluginBrowser.d.vue.ts +23 -0
- package/dist/runtime/components/registry/APluginBrowser.vue +155 -0
- package/dist/runtime/components/registry/APluginBrowser.vue.d.ts +23 -0
- package/dist/runtime/components/registry/APluginCapabilityDialog.d.vue.ts +17 -0
- package/dist/runtime/components/registry/APluginCapabilityDialog.vue +159 -0
- package/dist/runtime/components/registry/APluginCapabilityDialog.vue.d.ts +17 -0
- package/dist/runtime/components/registry/APluginCard.d.vue.ts +20 -0
- package/dist/runtime/components/registry/APluginCard.vue +91 -0
- package/dist/runtime/components/registry/APluginCard.vue.d.ts +20 -0
- package/dist/runtime/components/registry/APluginDetail.d.vue.ts +18 -0
- package/dist/runtime/components/registry/APluginDetail.vue +252 -0
- package/dist/runtime/components/registry/APluginDetail.vue.d.ts +18 -0
- package/dist/runtime/components/renderers/ACodeRenderer.d.vue.ts +15 -0
- package/dist/runtime/components/renderers/ACodeRenderer.vue +68 -0
- package/dist/runtime/components/renderers/ACodeRenderer.vue.d.ts +15 -0
- package/dist/runtime/components/renderers/AGraphRenderer.vue +416 -120
- package/dist/runtime/components/renderers/AProseRenderer.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/AProseRenderer.vue.d.ts +2 -2
- package/dist/runtime/components/shell/ABreadcrumbForDoc.d.vue.ts +11 -0
- package/dist/runtime/components/shell/ABreadcrumbForDoc.vue +16 -0
- package/dist/runtime/components/shell/ABreadcrumbForDoc.vue.d.ts +11 -0
- package/dist/runtime/components/shell/ASettingsSection.d.vue.ts +35 -0
- package/dist/runtime/components/shell/ASettingsSection.vue +26 -0
- package/dist/runtime/components/shell/ASettingsSection.vue.d.ts +35 -0
- package/dist/runtime/components/shell/ASidebar.d.vue.ts +1 -1
- package/dist/runtime/components/shell/ASidebar.vue.d.ts +1 -1
- package/dist/runtime/components/shell/AUserMenu.d.vue.ts +5 -2
- package/dist/runtime/components/shell/AUserMenu.vue +4 -0
- package/dist/runtime/components/shell/AUserMenu.vue.d.ts +5 -2
- package/dist/runtime/composables/useAbracadabraSchema.d.ts +83 -0
- package/dist/runtime/composables/useAbracadabraSchema.js +52 -0
- package/dist/runtime/composables/useAggregatedPresence.d.ts +1 -6
- package/dist/runtime/composables/useCalendarView.d.ts +1 -1
- package/dist/runtime/composables/useChat.js +1 -0
- package/dist/runtime/composables/useDocBreadcrumb.d.ts +21 -0
- package/dist/runtime/composables/useDocBreadcrumb.js +33 -0
- package/dist/runtime/composables/useDocEntryTyped.d.ts +60 -0
- package/dist/runtime/composables/useDocEntryTyped.js +70 -0
- package/dist/runtime/composables/useEditorDragHandle.js +18 -0
- package/dist/runtime/composables/useEditorSuggestions.js +2 -1
- package/dist/runtime/composables/useInstalledPlugins.d.ts +3 -21
- package/dist/runtime/composables/useInstalledPlugins.js +2 -12
- package/dist/runtime/composables/useMetaMenuItems.d.ts +21 -0
- package/dist/runtime/composables/useMetaMenuItems.js +115 -0
- package/dist/runtime/composables/useMetaValidator.d.ts +27 -0
- package/dist/runtime/composables/useMetaValidator.js +10 -0
- package/dist/runtime/composables/usePluginCatalog.d.ts +161 -0
- package/dist/runtime/composables/usePluginCatalog.js +234 -0
- package/dist/runtime/composables/useQuery.d.ts +79 -0
- package/dist/runtime/composables/useQuery.js +97 -0
- package/dist/runtime/composables/useSpaces.js +4 -5
- package/dist/runtime/composables/useTableView.d.ts +3 -3
- package/dist/runtime/composables/useTypedDoc.d.ts +97 -0
- package/dist/runtime/composables/useTypedDoc.js +114 -0
- package/dist/runtime/composables/useWebRTC.js +44 -5
- package/dist/runtime/extensions/document-meta.js +5 -0
- package/dist/runtime/extensions/timeline.d.ts +11 -0
- package/dist/runtime/extensions/timeline.js +52 -0
- package/dist/runtime/extensions/views/DocumentMetaView.d.vue.ts +4 -0
- package/dist/runtime/extensions/views/DocumentMetaView.vue +63 -0
- package/dist/runtime/extensions/views/DocumentMetaView.vue.d.ts +4 -0
- package/dist/runtime/extensions/views/TimelineItemView.d.vue.ts +4 -0
- package/dist/runtime/extensions/views/TimelineItemView.vue +131 -0
- package/dist/runtime/extensions/views/TimelineItemView.vue.d.ts +4 -0
- package/dist/runtime/extensions/views/TimelineView.d.vue.ts +9 -0
- package/dist/runtime/extensions/views/TimelineView.vue +29 -0
- package/dist/runtime/extensions/views/TimelineView.vue.d.ts +9 -0
- package/dist/runtime/locale.d.ts +2 -0
- package/dist/runtime/locale.js +2 -0
- package/dist/runtime/plugin-abracadabra.client.js +107 -6
- package/dist/runtime/plugin-registry.d.ts +11 -30
- package/dist/runtime/plugin-registry.js +2 -82
- package/dist/runtime/plugins/core.plugin.js +10 -4
- package/dist/runtime/server/api/_abracadabra/spaces.get.d.ts +1 -1
- package/dist/runtime/server/plugins/abracadabra-service.js +28 -0
- package/dist/runtime/server/utils/docCache.js +24 -3
- package/dist/runtime/server/utils/schemaServerSupport.d.ts +52 -0
- package/dist/runtime/server/utils/schemaServerSupport.js +51 -0
- package/dist/runtime/types.d.ts +63 -46
- package/dist/runtime/utils/docTypes.d.ts +15 -0
- package/dist/runtime/utils/docTypes.js +20 -0
- package/dist/runtime/utils/loadCodeMirror.d.ts +32 -0
- package/dist/runtime/utils/loadCodeMirror.js +65 -0
- package/dist/runtime/utils/markdownToYjs.d.ts +1 -23
- package/dist/runtime/utils/markdownToYjs.js +5 -440
- package/dist/runtime/utils/schemaSupport.d.ts +60 -0
- package/dist/runtime/utils/schemaSupport.js +40 -0
- package/dist/runtime/utils/yjsConvert.d.ts +1 -14
- package/dist/runtime/utils/yjsConvert.js +5 -331
- package/package.json +84 -23
|
@@ -7,15 +7,36 @@ export function initDocCache(storage, extraExtensions = []) {
|
|
|
7
7
|
_storage = storage;
|
|
8
8
|
_extensions = extraExtensions;
|
|
9
9
|
}
|
|
10
|
+
let _serverDoc = null;
|
|
11
|
+
async function getServerDoc() {
|
|
12
|
+
if (_serverDoc) return _serverDoc;
|
|
13
|
+
const happyDom = await import("happy-dom");
|
|
14
|
+
const Window = happyDom.Window ?? happyDom.default?.Window;
|
|
15
|
+
if (!Window) {
|
|
16
|
+
throw new Error("happy-dom did not export Window \u2014 install happy-dom or use the legacy DOM-global path.");
|
|
17
|
+
}
|
|
18
|
+
_serverDoc = new Window().document;
|
|
19
|
+
return _serverDoc;
|
|
20
|
+
}
|
|
10
21
|
async function renderDocToHTML(ydoc) {
|
|
11
22
|
try {
|
|
12
|
-
const [{
|
|
23
|
+
const [{ getSchema }, { yDocToProsemirrorJSON }, { default: StarterKit }, { Node, DOMSerializer }] = await Promise.all([
|
|
13
24
|
import("@tiptap/core"),
|
|
14
25
|
import("@tiptap/y-tiptap"),
|
|
15
|
-
import("@tiptap/starter-kit")
|
|
26
|
+
import("@tiptap/starter-kit"),
|
|
27
|
+
import("prosemirror-model")
|
|
16
28
|
]);
|
|
29
|
+
const schema = getSchema([StarterKit, ..._extensions]);
|
|
17
30
|
const json = yDocToProsemirrorJSON(ydoc, "default");
|
|
18
|
-
|
|
31
|
+
const node = Node.fromJSON(schema, json);
|
|
32
|
+
const serverDoc = await getServerDoc();
|
|
33
|
+
const container = serverDoc.createElement("div");
|
|
34
|
+
DOMSerializer.fromSchema(schema).serializeFragment(
|
|
35
|
+
node.content,
|
|
36
|
+
{ document: serverDoc },
|
|
37
|
+
container
|
|
38
|
+
);
|
|
39
|
+
return container.innerHTML;
|
|
19
40
|
} catch (e) {
|
|
20
41
|
console.warn("[abracadabra:doc-cache] HTML render failed:", e);
|
|
21
42
|
return null;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side mirror of `runtime/utils/schemaSupport.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Reuses the same dynamic-import pattern so a Nitro service plugin can
|
|
5
|
+
* advertise + delegate to `@abraca/schema` registries without forcing
|
|
6
|
+
* the package onto consumers that never opt in (Rule 2). Importing
|
|
7
|
+
* from `runtime/utils/schemaSupport.ts` directly would pull in browser-
|
|
8
|
+
* leaning client-side state (`shallowRef`, the Vue cache); this file
|
|
9
|
+
* is a thin Nitro-only re-implementation with no Vue dependency.
|
|
10
|
+
*/
|
|
11
|
+
/** Structural shape of a `@abraca/schema` SchemaRegistry. */
|
|
12
|
+
export interface SchemaRegistryLike<TMap = Record<string, unknown>> {
|
|
13
|
+
readonly types: ReadonlyMap<string, unknown>;
|
|
14
|
+
get: (name: string) => unknown;
|
|
15
|
+
validateMeta: (name: string, value: unknown) => ValidationResultLike;
|
|
16
|
+
validateChildType: (parent: string | null, child: string) => ValidationResultLike;
|
|
17
|
+
readonly __metaMap?: TMap;
|
|
18
|
+
}
|
|
19
|
+
export type ValidationResultLike = {
|
|
20
|
+
ok: true;
|
|
21
|
+
value: unknown;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
errors: ReadonlyArray<{
|
|
25
|
+
path: ReadonlyArray<PropertyKey>;
|
|
26
|
+
message: string;
|
|
27
|
+
code?: string;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
/** Subset of the `@abraca/schema` public surface the server needs at runtime. */
|
|
31
|
+
export interface ServerSchemaModule {
|
|
32
|
+
defineSchema: (spec: {
|
|
33
|
+
types: ReadonlyArray<unknown>;
|
|
34
|
+
}) => SchemaRegistryLike;
|
|
35
|
+
defineDocType: (spec: unknown) => unknown;
|
|
36
|
+
runMigrations: (registry: SchemaRegistryLike, typeName: string, meta: unknown) => unknown;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve `@abraca/schema` if it is installed alongside the Nuxt app.
|
|
40
|
+
*
|
|
41
|
+
* Returns `null` (and warns once) when the package is missing or fails
|
|
42
|
+
* to import. Caches the result; subsequent calls reuse it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function tryLoadServerSchemaModule(): Promise<ServerSchemaModule | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Build a merged "first-registry-wins" validator from a list of attached
|
|
47
|
+
* registries. Returns null when no registries provide a matching type
|
|
48
|
+
* (Rule 4: pass-through for unknown doc-types).
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildServerSchemaValidator(registries: ReadonlyArray<SchemaRegistryLike>): ((typeName: string, meta: unknown) => ValidationResultLike) | null;
|
|
51
|
+
/** Test-only — reset the cached resolution. */
|
|
52
|
+
export declare function __resetServerSchemaSupportCacheForTests(): void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
let cached;
|
|
2
|
+
let loading = null;
|
|
3
|
+
let warned = false;
|
|
4
|
+
export async function tryLoadServerSchemaModule() {
|
|
5
|
+
if (cached !== void 0) return cached;
|
|
6
|
+
if (loading) return loading;
|
|
7
|
+
loading = (async () => {
|
|
8
|
+
try {
|
|
9
|
+
const mod = await import("@abraca/schema");
|
|
10
|
+
const candidate = {
|
|
11
|
+
defineSchema: mod.defineSchema,
|
|
12
|
+
defineDocType: mod.defineDocType,
|
|
13
|
+
runMigrations: mod.runMigrations
|
|
14
|
+
};
|
|
15
|
+
if (typeof candidate.defineSchema !== "function" || typeof candidate.defineDocType !== "function" || typeof candidate.runMigrations !== "function") {
|
|
16
|
+
throw new TypeError("unexpected @abraca/schema shape \u2014 missing one of defineSchema / defineDocType / runMigrations");
|
|
17
|
+
}
|
|
18
|
+
cached = candidate;
|
|
19
|
+
return cached;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
if (!warned) {
|
|
22
|
+
warned = true;
|
|
23
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
24
|
+
console.warn(
|
|
25
|
+
`[abracadabra-service] schema integration requested but @abraca/schema could not be loaded \u2014 install it as a peer dependency to enable server-side typed surfaces (${reason})`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
cached = null;
|
|
29
|
+
return null;
|
|
30
|
+
} finally {
|
|
31
|
+
loading = null;
|
|
32
|
+
}
|
|
33
|
+
})();
|
|
34
|
+
return loading;
|
|
35
|
+
}
|
|
36
|
+
export function buildServerSchemaValidator(registries) {
|
|
37
|
+
if (registries.length === 0) return null;
|
|
38
|
+
return (typeName, meta) => {
|
|
39
|
+
for (const r of registries) {
|
|
40
|
+
if (r.types.has(typeName)) {
|
|
41
|
+
return r.validateMeta(typeName, meta);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { ok: true, value: meta };
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function __resetServerSchemaSupportCacheForTests() {
|
|
48
|
+
cached = void 0;
|
|
49
|
+
loading = null;
|
|
50
|
+
warned = false;
|
|
51
|
+
}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1,49 +1,39 @@
|
|
|
1
1
|
import type { ShallowRef, Ref, Component } from 'vue';
|
|
2
|
-
import type { Extension } from '@tiptap/core';
|
|
3
2
|
import type { Editor } from '@tiptap/vue-3';
|
|
4
3
|
import type { Node as ProsemirrorNode } from '@tiptap/pm/model';
|
|
5
4
|
import type * as Y from 'yjs';
|
|
6
5
|
import type { AbracadabraClient, AbracadabraProvider, AbracadabraWS, CryptoIdentityKeystore } from '@abraca/dabra';
|
|
7
6
|
import type { Router } from 'vue-router';
|
|
7
|
+
import type { AbraPlugin, AbraAwarenessContribution as BaseAbraAwarenessContribution, AbraNodePanelSlot as BaseAbraNodePanelSlot, AbraSettingsPanel as BaseAbraSettingsPanel, AbraKeyboardShortcut as BaseAbraKeyboardShortcut, AbraMentionItem } from '@abraca/plugin';
|
|
8
8
|
/**
|
|
9
9
|
* An Abracadabra plugin contributes editor extensions, page types, toolbar items,
|
|
10
10
|
* slash commands, mentions, awareness fields, command palette items, and more.
|
|
11
11
|
*
|
|
12
12
|
* Plugins are registered before the registry is frozen at boot.
|
|
13
13
|
* After freezing all contributions are stable for the lifetime of the app.
|
|
14
|
+
*
|
|
15
|
+
* `AbracadabraPlugin` is a tightened alias of `@abraca/plugin`'s universal
|
|
16
|
+
* `AbraPlugin` — same shape, but contribution fields are narrowed to the
|
|
17
|
+
* module's concrete types (`AbracadabraToolbarItem`, `AbracadabraPageType`,
|
|
18
|
+
* `AbracadabraState`-aware setup context, etc.).
|
|
14
19
|
*/
|
|
15
|
-
export interface AbracadabraPlugin {
|
|
16
|
-
/** Unique slug — must be stable across versions, e.g. 'core', 'kanban', 'my-plugin' */
|
|
17
|
-
name: string;
|
|
18
|
-
label?: string;
|
|
19
|
-
version?: string;
|
|
20
|
-
description?: string;
|
|
21
|
-
/** TipTap extensions (nodes, marks, extensions) contributed by this plugin */
|
|
22
|
-
extensions?: () => Extension[];
|
|
23
|
-
/**
|
|
24
|
-
* Optional promise that resolves when this plugin's extensions are fully
|
|
25
|
-
* loaded. Used by PluginRegistry.waitForExtensions() to ensure the editor
|
|
26
|
-
* doesn't initialize before async extension bundles are ready.
|
|
27
|
-
*/
|
|
28
|
-
extensionsReady?: Promise<void>;
|
|
20
|
+
export interface AbracadabraPlugin extends AbraPlugin {
|
|
29
21
|
/** Document/page type renderers keyed by type slug */
|
|
30
22
|
pageTypes?: Record<string, AbracadabraPageType>;
|
|
31
23
|
/** Extra toolbar item groups appended after the built-in toolbar groups */
|
|
32
|
-
toolbarItems
|
|
24
|
+
toolbarItems?(ctx: EditorPluginCtx): AbracadabraToolbarItem[][];
|
|
33
25
|
/** Extra bubble menu item groups (appear on text selection) */
|
|
34
|
-
bubbleMenuItems
|
|
26
|
+
bubbleMenuItems?(ctx: EditorPluginCtx): AbracadabraToolbarItem[][];
|
|
35
27
|
/** Slash command (/) suggestion menu item groups */
|
|
36
|
-
suggestionItems
|
|
28
|
+
suggestionItems?(ctx: EditorPluginCtx): AbracadabraSuggestionItem[][];
|
|
37
29
|
/** Extra drag-handle menu items (per-block context menu) */
|
|
38
|
-
dragHandleItems
|
|
39
|
-
/** Custom editor handlers merged into UEditorCustomHandlers */
|
|
40
|
-
customHandlers?: () => Record<string, (...args: unknown[]) => unknown>;
|
|
30
|
+
dragHandleItems?(ctx: DragHandlePluginCtx): AbracadabraDragHandleItem[][];
|
|
41
31
|
/** Mention (@) providers contributing items to the mention popup */
|
|
42
32
|
mentionProviders?: AbracadabraMentionProvider[];
|
|
43
33
|
/** Awareness field declarations — keys this plugin reads/writes on awareness */
|
|
44
34
|
awarenessContributions?: AbracadabraAwarenessContribution[];
|
|
45
35
|
/** Global command palette (⌘K) items */
|
|
46
|
-
commandPaletteItems
|
|
36
|
+
commandPaletteItems?(ctx: CommandPaletteCtx): AbracadabraCommandItem[] | Promise<AbracadabraCommandItem[]>;
|
|
47
37
|
/** Extra tabs rendered in the child document slideover panel */
|
|
48
38
|
nodePanelSlots?: AbracadabraNodePanelSlot[];
|
|
49
39
|
/** Settings panel contributed to the global settings view */
|
|
@@ -54,14 +44,7 @@ export interface AbracadabraPlugin {
|
|
|
54
44
|
* Client-side setup hook — called once after client + provider are ready.
|
|
55
45
|
* May return a teardown function called on app unmount.
|
|
56
46
|
*/
|
|
57
|
-
clientSetup
|
|
58
|
-
/** TipTap extensions safe for server-side Y.Doc → HTML rendering (no Vue NodeViews) */
|
|
59
|
-
serverExtensions?: () => Extension[];
|
|
60
|
-
/**
|
|
61
|
-
* Custom cache renderer for non-doc page types.
|
|
62
|
-
* Receives the Y.Doc and returns serializable data for the cache.
|
|
63
|
-
*/
|
|
64
|
-
serverCacheRenderer?: (docId: string, ydoc: Y.Doc) => unknown;
|
|
47
|
+
clientSetup?(ctx: ClientPluginCtx): undefined | Promise<undefined | (() => void)>;
|
|
65
48
|
/**
|
|
66
49
|
* Server-side background runners (Nitro context).
|
|
67
50
|
* Each runner receives a ServerRunnerContext and returns a cleanup function.
|
|
@@ -165,37 +148,32 @@ export interface AbracadabraCommandItem {
|
|
|
165
148
|
icon?: string;
|
|
166
149
|
group?: string;
|
|
167
150
|
shortcut?: string;
|
|
168
|
-
when
|
|
169
|
-
handler
|
|
151
|
+
when?(ctx: CommandPaletteCtx): boolean;
|
|
152
|
+
handler(ctx: CommandPaletteCtx): void | Promise<void>;
|
|
170
153
|
}
|
|
171
154
|
export interface AbracadabraMentionProvider {
|
|
172
155
|
/** Group label shown in the suggestion popup */
|
|
173
156
|
label: string;
|
|
174
|
-
getItems
|
|
157
|
+
getItems(query: string, ctx: MentionPluginCtx): AbracadabraMentionItem[] | Promise<AbracadabraMentionItem[]>;
|
|
175
158
|
}
|
|
176
159
|
export interface MentionPluginCtx {
|
|
177
160
|
docId: string;
|
|
178
161
|
connectedUsers: CollaborationUser[];
|
|
179
162
|
rootDoc: Y.Doc;
|
|
180
163
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
avatar?: string;
|
|
185
|
-
color?: string;
|
|
186
|
-
attrs?: Record<string, unknown>;
|
|
187
|
-
}
|
|
188
|
-
export interface AbracadabraAwarenessContribution {
|
|
164
|
+
/** Module-level alias of `AbraMentionItem` for callers that import from `@abraca/nuxt`. */
|
|
165
|
+
export type AbracadabraMentionItem = AbraMentionItem;
|
|
166
|
+
export interface AbracadabraAwarenessContribution extends BaseAbraAwarenessContribution {
|
|
189
167
|
/** Namespaced keys this plugin writes, e.g. ['cursor', 'presence:kanban'] */
|
|
190
168
|
keys: string[];
|
|
191
169
|
/** Optional per-canvas cursor overlay component */
|
|
192
170
|
cursorComponent?: Component;
|
|
193
171
|
}
|
|
194
|
-
export interface AbracadabraNodePanelSlot {
|
|
172
|
+
export interface AbracadabraNodePanelSlot extends Omit<BaseAbraNodePanelSlot, 'when' | 'component'> {
|
|
195
173
|
id: string;
|
|
196
174
|
label: string;
|
|
197
175
|
icon: string;
|
|
198
|
-
when
|
|
176
|
+
when(ctx: NodePanelCtx): boolean;
|
|
199
177
|
component: Component;
|
|
200
178
|
}
|
|
201
179
|
export interface NodePanelCtx {
|
|
@@ -206,12 +184,12 @@ export interface NodePanelCtx {
|
|
|
206
184
|
meta: Record<string, unknown>;
|
|
207
185
|
tree: DocTreeHelper;
|
|
208
186
|
}
|
|
209
|
-
export interface AbracadabraSettingsPanel {
|
|
187
|
+
export interface AbracadabraSettingsPanel extends Omit<BaseAbraSettingsPanel, 'component'> {
|
|
210
188
|
label: string;
|
|
211
189
|
icon: string;
|
|
212
190
|
component: Component;
|
|
213
191
|
}
|
|
214
|
-
export interface AbracadabraKeyboardShortcut {
|
|
192
|
+
export interface AbracadabraKeyboardShortcut extends BaseAbraKeyboardShortcut {
|
|
215
193
|
/** e.g. 'Meta+Shift+K', 'Control+Alt+P' */
|
|
216
194
|
key: string;
|
|
217
195
|
description: string;
|
|
@@ -577,6 +555,45 @@ export interface ServerRunnerContext {
|
|
|
577
555
|
storage: NitroStorage;
|
|
578
556
|
/** Document cache API: read/write HTML+JSON renders, build tree snapshots */
|
|
579
557
|
docCache: DocCacheAPI;
|
|
558
|
+
/**
|
|
559
|
+
* Pre-write meta validator built from any `@abraca/schema` registries
|
|
560
|
+
* Nitro plugins attached via `BeforeRunnersCtx.attachSchema(...)` during
|
|
561
|
+
* the `abracadabra:before-runners` hook. `undefined` when no plugin
|
|
562
|
+
* attached a registry — runners must short-circuit on `undefined`
|
|
563
|
+
* rather than treating absence as "all writes are invalid" (Rule 4).
|
|
564
|
+
*
|
|
565
|
+
* Returns `{ ok: true, value }` for unknown doc-types — the validator
|
|
566
|
+
* mirrors the server's bundle_path / bundle_dir skip-on-collision rule.
|
|
567
|
+
*/
|
|
568
|
+
validateMeta?: (typeName: string, meta: unknown) => {
|
|
569
|
+
ok: true;
|
|
570
|
+
value?: unknown;
|
|
571
|
+
} | {
|
|
572
|
+
ok: false;
|
|
573
|
+
errors: ReadonlyArray<{
|
|
574
|
+
path: ReadonlyArray<PropertyKey>;
|
|
575
|
+
message: string;
|
|
576
|
+
code?: string;
|
|
577
|
+
}>;
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Payload of the `abracadabra:before-runners` Nitro hook. Plugins can
|
|
582
|
+
* register runners (`registerServerPlugin(plugin)`) and/or attach
|
|
583
|
+
* `@abraca/schema` registries (`attachSchema(registry)`) before the
|
|
584
|
+
* runner boot fires.
|
|
585
|
+
*/
|
|
586
|
+
export interface BeforeRunnersCtx extends ServerRunnerContext {
|
|
587
|
+
/**
|
|
588
|
+
* Attach a SchemaRegistry. Multiple calls accumulate. Validators are
|
|
589
|
+
* built in attach order — the first registry that recognises a type
|
|
590
|
+
* wins. Mirrors the server's bundle_path / bundle_dir behaviour.
|
|
591
|
+
*
|
|
592
|
+
* Available even when `@abraca/schema` is not installed — just collects
|
|
593
|
+
* the references for downstream `validateMeta` wiring; if no module
|
|
594
|
+
* is present the cumulative validator is still safe to call.
|
|
595
|
+
*/
|
|
596
|
+
attachSchema?: (registry: import('./server/utils/schemaServerSupport').SchemaRegistryLike) => void;
|
|
580
597
|
}
|
|
581
598
|
/**
|
|
582
599
|
* A named background task that runs inside the Nitro server process.
|
|
@@ -584,7 +601,7 @@ export interface ServerRunnerContext {
|
|
|
584
601
|
*/
|
|
585
602
|
export interface ServerRunnerDefinition {
|
|
586
603
|
name: string;
|
|
587
|
-
start
|
|
604
|
+
start(ctx: ServerRunnerContext): Promise<RunnerCleanup>;
|
|
588
605
|
}
|
|
589
606
|
/**
|
|
590
607
|
* API surface for reading/writing cached document renders.
|
|
@@ -148,6 +148,21 @@ export interface DocTypeDefinition {
|
|
|
148
148
|
grandchildLabel?: string;
|
|
149
149
|
/** Metadata fields shown/edited in the document properties panel. */
|
|
150
150
|
metaSchema?: MetaField[];
|
|
151
|
+
/**
|
|
152
|
+
* Optional `@abraca/schema` registry that governs the data shape of
|
|
153
|
+
* this doc-type's `meta` field. Orthogonal to `metaSchema` (UI-form
|
|
154
|
+
* declarations) — `dataSchema` is the wire-level validator surface.
|
|
155
|
+
*
|
|
156
|
+
* When set, renderers can read with `useDocEntryTyped(id, dataSchema, key)`
|
|
157
|
+
* and write through `useTypedDoc(dataSchema)` to get type-narrowed
|
|
158
|
+
* meta and pre-write validation. Built-in `DOC_TYPES` records leave
|
|
159
|
+
* this undefined — apps wire it themselves so the canonical schemas
|
|
160
|
+
* stay opt-in (Rule 2).
|
|
161
|
+
*
|
|
162
|
+
* Typed as `SchemaRegistryLike` (structural, no static peer-dep
|
|
163
|
+
* import) so this file stays buildable without `@abraca/schema`.
|
|
164
|
+
*/
|
|
165
|
+
dataSchema?: import('./schemaSupport').SchemaRegistryLike;
|
|
151
166
|
}
|
|
152
167
|
/**
|
|
153
168
|
* Per-geoType meta schemas. Used by AEditor to show the right fields
|
|
@@ -81,6 +81,26 @@ export const DOC_TYPES = {
|
|
|
81
81
|
() => import("../components/renderers/AProseRenderer.vue")
|
|
82
82
|
)
|
|
83
83
|
},
|
|
84
|
+
code: {
|
|
85
|
+
key: "code",
|
|
86
|
+
label: "Code",
|
|
87
|
+
icon: "i-lucide-code-2",
|
|
88
|
+
description: "Collaborative plain-text code editor with syntax highlighting",
|
|
89
|
+
available: true,
|
|
90
|
+
hasEditor: false,
|
|
91
|
+
supportsChildren: false,
|
|
92
|
+
component: defineDocComponent(
|
|
93
|
+
() => import("../components/renderers/ACodeRenderer.vue")
|
|
94
|
+
),
|
|
95
|
+
metaSchema: [
|
|
96
|
+
{
|
|
97
|
+
type: "select",
|
|
98
|
+
key: "language",
|
|
99
|
+
options: ["javascript", "typescript", "tsx", "jsx", "css", "vue", "json", "markdown", "plain"],
|
|
100
|
+
label: "Language"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
84
104
|
kanban: {
|
|
85
105
|
key: "kanban",
|
|
86
106
|
label: "Kanban",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loadCodeMirror — try-import the CodeMirror peer dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Returns a bundle of the modules needed by <ACodeEditor> if the consumer
|
|
5
|
+
* installed them, or `null` if any required package is missing. Cached after
|
|
6
|
+
* the first call; the first failed lookup logs once in dev.
|
|
7
|
+
*
|
|
8
|
+
* Required peers: codemirror, @codemirror/state, @codemirror/view,
|
|
9
|
+
* @codemirror/language, @codemirror/commands, @codemirror/autocomplete,
|
|
10
|
+
* @codemirror/search, @codemirror/lang-javascript, @codemirror/lang-css,
|
|
11
|
+
* @codemirror/lang-vue, @codemirror/lang-json, y-codemirror.next.
|
|
12
|
+
*
|
|
13
|
+
* Apps that want code editing install:
|
|
14
|
+
* pnpm add codemirror @codemirror/state @codemirror/view @codemirror/language \
|
|
15
|
+
* @codemirror/commands @codemirror/autocomplete @codemirror/search \
|
|
16
|
+
* @codemirror/lang-javascript @codemirror/lang-css @codemirror/lang-vue \
|
|
17
|
+
* @codemirror/lang-json y-codemirror.next
|
|
18
|
+
*/
|
|
19
|
+
export interface CodeMirrorBundle {
|
|
20
|
+
view: typeof import('@codemirror/view');
|
|
21
|
+
state: typeof import('@codemirror/state');
|
|
22
|
+
language: typeof import('@codemirror/language');
|
|
23
|
+
commands: typeof import('@codemirror/commands');
|
|
24
|
+
autocomplete: typeof import('@codemirror/autocomplete');
|
|
25
|
+
search: typeof import('@codemirror/search');
|
|
26
|
+
langJavascript: typeof import('@codemirror/lang-javascript');
|
|
27
|
+
langCss: typeof import('@codemirror/lang-css');
|
|
28
|
+
langVue: typeof import('@codemirror/lang-vue');
|
|
29
|
+
langJson: typeof import('@codemirror/lang-json');
|
|
30
|
+
yCollab: typeof import('y-codemirror.next');
|
|
31
|
+
}
|
|
32
|
+
export declare function loadCodeMirror(): Promise<CodeMirrorBundle | null>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
let cache = null;
|
|
2
|
+
let loading = null;
|
|
3
|
+
let warnedMissing = false;
|
|
4
|
+
export async function loadCodeMirror() {
|
|
5
|
+
if (cache) return cache;
|
|
6
|
+
if (loading) return loading;
|
|
7
|
+
loading = (async () => {
|
|
8
|
+
try {
|
|
9
|
+
const names = [
|
|
10
|
+
"@codemirror/view",
|
|
11
|
+
"@codemirror/state",
|
|
12
|
+
"@codemirror/language",
|
|
13
|
+
"@codemirror/commands",
|
|
14
|
+
"@codemirror/autocomplete",
|
|
15
|
+
"@codemirror/search",
|
|
16
|
+
"@codemirror/lang-javascript",
|
|
17
|
+
"@codemirror/lang-css",
|
|
18
|
+
"@codemirror/lang-vue",
|
|
19
|
+
"@codemirror/lang-json",
|
|
20
|
+
"y-codemirror.next"
|
|
21
|
+
];
|
|
22
|
+
const [
|
|
23
|
+
view,
|
|
24
|
+
state,
|
|
25
|
+
language,
|
|
26
|
+
commands,
|
|
27
|
+
autocomplete,
|
|
28
|
+
search,
|
|
29
|
+
langJavascript,
|
|
30
|
+
langCss,
|
|
31
|
+
langVue,
|
|
32
|
+
langJson,
|
|
33
|
+
yCollab
|
|
34
|
+
] = await Promise.all(names.map((n) => import(
|
|
35
|
+
/* @vite-ignore */
|
|
36
|
+
n
|
|
37
|
+
)));
|
|
38
|
+
cache = {
|
|
39
|
+
view,
|
|
40
|
+
state,
|
|
41
|
+
language,
|
|
42
|
+
commands,
|
|
43
|
+
autocomplete,
|
|
44
|
+
search,
|
|
45
|
+
langJavascript,
|
|
46
|
+
langCss,
|
|
47
|
+
langVue,
|
|
48
|
+
langJson,
|
|
49
|
+
yCollab
|
|
50
|
+
};
|
|
51
|
+
return cache;
|
|
52
|
+
} catch {
|
|
53
|
+
if (import.meta.dev && !warnedMissing) {
|
|
54
|
+
warnedMissing = true;
|
|
55
|
+
console.warn(
|
|
56
|
+
"[abracadabra] CodeMirror peer dependencies not installed. Code page type will fall back to a read-only <textarea>. Install: pnpm add codemirror @codemirror/state @codemirror/view @codemirror/language @codemirror/commands @codemirror/autocomplete @codemirror/search @codemirror/lang-javascript @codemirror/lang-css @codemirror/lang-vue @codemirror/lang-json y-codemirror.next"
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
} finally {
|
|
61
|
+
loading = null;
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
return loading;
|
|
65
|
+
}
|
|
@@ -1,23 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* markdownToYjs.ts
|
|
3
|
-
*
|
|
4
|
-
* Parses markdown and populates a Y.XmlFragment with TipTap-compatible nodes.
|
|
5
|
-
* Also provides YAML frontmatter parsing and filename → label conversion.
|
|
6
|
-
*
|
|
7
|
-
* Ported from cou-sh/app/utils/markdownToYjs.ts
|
|
8
|
-
*/
|
|
9
|
-
import * as Y from 'yjs';
|
|
10
|
-
import type { DocPageMeta } from '../types.js';
|
|
11
|
-
export declare function filenameToLabel(raw: string): string;
|
|
12
|
-
export interface FrontmatterResult {
|
|
13
|
-
title?: string;
|
|
14
|
-
type?: string;
|
|
15
|
-
meta: Partial<DocPageMeta>;
|
|
16
|
-
body: string;
|
|
17
|
-
}
|
|
18
|
-
export declare function parseFrontmatter(markdown: string): FrontmatterResult;
|
|
19
|
-
/**
|
|
20
|
-
* Parses markdown and writes content into a Y.XmlFragment.
|
|
21
|
-
* The fragment must already be attached to a live Y.Doc.
|
|
22
|
-
*/
|
|
23
|
-
export declare function populateYDocFromMarkdown(fragment: Y.XmlFragment, markdown: string, fallbackTitle?: string): void;
|
|
1
|
+
export { filenameToLabel, parseFrontmatter, populateYDocFromMarkdown, type FrontmatterResult, } from '@abraca/convert';
|