@blokkli/editor 2.0.0-alpha.64 → 2.0.0-alpha.65
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 +2 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +48 -2
- package/dist/modules/agent/index.d.mts +1 -1
- package/dist/modules/agent/runtime/app/helpers/mutationResult.d.ts +12 -0
- package/dist/modules/agent/runtime/app/helpers/mutationResult.js +34 -0
- package/dist/modules/agent/runtime/app/providers/toolsProvider.js +13 -7
- package/dist/modules/agent/runtime/app/tools/add_paragraphs/index.d.ts +15 -4
- package/dist/modules/agent/runtime/app/tools/add_paragraphs/index.js +43 -15
- package/dist/modules/agent/runtime/server/server-tools/load_tools/index.d.ts +1 -3
- package/dist/modules/agent/runtime/server/server-tools/load_tools/index.js +3 -1
- package/dist/modules/charts/index.d.mts +1 -1
- package/dist/modules/drupal/index.d.mts +1 -1
- package/dist/modules/iframes/index.d.mts +1 -1
- package/dist/modules/index.d.mts +1 -1
- package/dist/modules/readability/index.d.mts +1 -1
- package/dist/modules/table-of-contents/index.d.mts +1 -1
- package/dist/runtime/editor/components/FlexTextarea/index.d.vue.ts +1 -1
- package/dist/runtime/editor/components/FlexTextarea/index.vue.d.ts +1 -1
- package/dist/runtime/editor/plugins/ItemAction/index.d.vue.ts +1 -1
- package/dist/runtime/editor/plugins/ItemAction/index.vue.d.ts +1 -1
- package/dist/runtime/editor/plugins/Sidebar/Detached/index.d.vue.ts +1 -1
- package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue.d.ts +1 -1
- package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +2 -2
- package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +2 -2
- package/dist/runtime/editor/providers/state.d.ts +17 -1
- package/dist/runtime/editor/providers/state.js +14 -0
- package/dist/shared/{editor.BDyiQvbV.d.mts → editor.S5sA3rij.d.mts} +19 -1
- package/dist/types.d.mts +1 -1
- package/package.json +1 -1
package/dist/module.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NuxtModule } from 'nuxt/schema';
|
|
2
|
-
import { M as ModuleOptions } from './shared/editor.
|
|
3
|
-
export { a as ModuleHooks } from './shared/editor.
|
|
2
|
+
import { M as ModuleOptions } from './shared/editor.S5sA3rij.mjs';
|
|
3
|
+
export { a as ModuleHooks } from './shared/editor.S5sA3rij.mjs';
|
|
4
4
|
import 'consola';
|
|
5
5
|
import '../dist/global/types/definitions.js';
|
|
6
6
|
import '../dist/global/types/theme.js';
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import 'typescript';
|
|
|
19
19
|
import 'oxc-walker';
|
|
20
20
|
|
|
21
21
|
const name = "@blokkli/editor";
|
|
22
|
-
const version = "2.0.0-alpha.
|
|
22
|
+
const version = "2.0.0-alpha.65";
|
|
23
23
|
|
|
24
24
|
function validateOption(optionKey, option, icons) {
|
|
25
25
|
const errors = [];
|
|
@@ -1203,6 +1203,11 @@ class ModuleHelper {
|
|
|
1203
1203
|
* module and enabled sub-modules. Flushed by {@link applyBuildConfig}.
|
|
1204
1204
|
*/
|
|
1205
1205
|
packageDependencies = /* @__PURE__ */ new Set();
|
|
1206
|
+
/**
|
|
1207
|
+
* npm packages that must resolve to a single copy across the whole app.
|
|
1208
|
+
* Flushed to Vite's resolve.dedupe by {@link applyBuildConfig}.
|
|
1209
|
+
*/
|
|
1210
|
+
dedupedPackages = /* @__PURE__ */ new Set();
|
|
1206
1211
|
isDev;
|
|
1207
1212
|
isModuleBuild;
|
|
1208
1213
|
isPrepare;
|
|
@@ -1279,11 +1284,28 @@ class ModuleHelper {
|
|
|
1279
1284
|
this.packageDependencies.add(name);
|
|
1280
1285
|
}
|
|
1281
1286
|
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Declare packages that must only ever exist once in the module graph.
|
|
1289
|
+
*
|
|
1290
|
+
* Libraries that rely on `instanceof` checks or module-level registries break
|
|
1291
|
+
* when a project's install tree ends up with two copies (e.g. a hoisted
|
|
1292
|
+
* version plus an older one nested under a transitive dependency). Forcing
|
|
1293
|
+
* resolution to a single copy makes the editor work regardless of how the
|
|
1294
|
+
* host project's package manager arranged node_modules.
|
|
1295
|
+
*
|
|
1296
|
+
* @param names - Bare package specifiers (e.g. 'prosemirror-model').
|
|
1297
|
+
*/
|
|
1298
|
+
addDedupedPackage(...names) {
|
|
1299
|
+
for (const name of names) {
|
|
1300
|
+
this.dedupedPackages.add(name);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1282
1303
|
/**
|
|
1283
1304
|
* Apply collected build configuration to the Nuxt/Vite config.
|
|
1284
1305
|
*
|
|
1285
1306
|
* Called once by the core module after every module's setup has run, so it
|
|
1286
|
-
* sees the full set of {@link addPackageDependency}
|
|
1307
|
+
* sees the full set of {@link addPackageDependency} and
|
|
1308
|
+
* {@link addDedupedPackage} registrations.
|
|
1287
1309
|
*/
|
|
1288
1310
|
applyBuildConfig() {
|
|
1289
1311
|
this.nuxt.options.vite.optimizeDeps ??= {};
|
|
@@ -1295,6 +1317,13 @@ class ModuleHelper {
|
|
|
1295
1317
|
}
|
|
1296
1318
|
include.push(name);
|
|
1297
1319
|
}
|
|
1320
|
+
this.nuxt.options.vite.resolve ??= {};
|
|
1321
|
+
const dedupe = this.nuxt.options.vite.resolve.dedupe ??= [];
|
|
1322
|
+
for (const name of this.dedupedPackages) {
|
|
1323
|
+
if (!dedupe.includes(name)) {
|
|
1324
|
+
dedupe.push(name);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1298
1327
|
}
|
|
1299
1328
|
addAlias(name, path) {
|
|
1300
1329
|
this.nuxt.options.alias[name] = path;
|
|
@@ -4695,6 +4724,23 @@ const module$1 = defineNuxtModule({
|
|
|
4695
4724
|
"qrcode.vue",
|
|
4696
4725
|
"twgl.js"
|
|
4697
4726
|
);
|
|
4727
|
+
helper.addDedupedPackage(
|
|
4728
|
+
"@tiptap/core",
|
|
4729
|
+
"@tiptap/pm",
|
|
4730
|
+
"prosemirror-changeset",
|
|
4731
|
+
"prosemirror-commands",
|
|
4732
|
+
"prosemirror-dropcursor",
|
|
4733
|
+
"prosemirror-gapcursor",
|
|
4734
|
+
"prosemirror-history",
|
|
4735
|
+
"prosemirror-inputrules",
|
|
4736
|
+
"prosemirror-keymap",
|
|
4737
|
+
"prosemirror-model",
|
|
4738
|
+
"prosemirror-schema-list",
|
|
4739
|
+
"prosemirror-state",
|
|
4740
|
+
"prosemirror-tables",
|
|
4741
|
+
"prosemirror-transform",
|
|
4742
|
+
"prosemirror-view"
|
|
4743
|
+
);
|
|
4698
4744
|
helper.applyBuildConfig();
|
|
4699
4745
|
helper.addComponent("BlokkliField");
|
|
4700
4746
|
helper.addComponent("BlokkliEditable");
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BlokkliApp } from '#blokkli/editor/types/app';
|
|
2
|
+
import type { MutationResponseLike } from '#blokkli/editor/adapter';
|
|
2
3
|
/**
|
|
3
4
|
* Tree-shaped entry in the `newParagraphs` payload returned by mutation tools.
|
|
4
5
|
*
|
|
@@ -27,6 +28,17 @@ export type NewParagraphNode = {
|
|
|
27
28
|
* round-trips are needed.
|
|
28
29
|
*/
|
|
29
30
|
export declare function buildNewParagraphsTree(newUuids: string[], app: BlokkliApp, itemEntityType: string): NewParagraphNode[];
|
|
31
|
+
/**
|
|
32
|
+
* Compose an agent-facing error message from a rejected mutation response.
|
|
33
|
+
*
|
|
34
|
+
* Backends return structured `violations` (field-level constraint failures)
|
|
35
|
+
* and/or plain `errors`. Violations carry the useful context (which field on
|
|
36
|
+
* which entity failed and why), so they're preferred; the generic `errors`
|
|
37
|
+
* list (e.g. Drupal's catch-all "Entity Violations") is only used as a
|
|
38
|
+
* fallback when no violations are present. The result is surfaced to the LLM
|
|
39
|
+
* so it can correct the mutation (e.g. supply the missing required field).
|
|
40
|
+
*/
|
|
41
|
+
export declare function formatMutationFailure(response: MutationResponseLike<any> | undefined): string;
|
|
30
42
|
/**
|
|
31
43
|
* Count every node in a `newParagraphs` tree, including nested children.
|
|
32
44
|
*
|
|
@@ -35,6 +35,40 @@ export function buildNewParagraphsTree(newUuids, app, itemEntityType) {
|
|
|
35
35
|
}
|
|
36
36
|
return roots;
|
|
37
37
|
}
|
|
38
|
+
function violationLocation(violation) {
|
|
39
|
+
const parts = [];
|
|
40
|
+
if (violation.propertyPath) {
|
|
41
|
+
parts.push(violation.propertyPath);
|
|
42
|
+
}
|
|
43
|
+
if (violation.entityUuid) {
|
|
44
|
+
const entity = violation.entityType ?? "entity";
|
|
45
|
+
parts.push(
|
|
46
|
+
violation.propertyPath ? `(${entity} ${violation.entityUuid})` : `${entity} ${violation.entityUuid}`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return parts.join(" ");
|
|
50
|
+
}
|
|
51
|
+
export function formatMutationFailure(response) {
|
|
52
|
+
if (!response) {
|
|
53
|
+
return "The mutation failed: the backend returned no response.";
|
|
54
|
+
}
|
|
55
|
+
const violations = response.violations ?? [];
|
|
56
|
+
if (violations.length) {
|
|
57
|
+
const lines = violations.map((violation) => {
|
|
58
|
+
const location = violationLocation(violation);
|
|
59
|
+
return location ? `- ${location}: ${violation.message}` : `- ${violation.message}`;
|
|
60
|
+
});
|
|
61
|
+
return `The mutation was rejected by the backend:
|
|
62
|
+
${lines.join("\n")}`;
|
|
63
|
+
}
|
|
64
|
+
const errors = (response.errors ?? []).filter(Boolean);
|
|
65
|
+
if (errors.length) {
|
|
66
|
+
const lines = errors.map((error) => `- ${error}`);
|
|
67
|
+
return `The mutation was rejected by the backend:
|
|
68
|
+
${lines.join("\n")}`;
|
|
69
|
+
}
|
|
70
|
+
return "The mutation was rejected by the backend.";
|
|
71
|
+
}
|
|
38
72
|
export function countNewParagraphs(nodes) {
|
|
39
73
|
let total = 0;
|
|
40
74
|
for (const node of nodes) {
|
|
@@ -11,7 +11,10 @@ import {
|
|
|
11
11
|
asRecord,
|
|
12
12
|
splitMeta
|
|
13
13
|
} from "#blokkli/agent/app/helpers";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
buildNewParagraphsTree,
|
|
16
|
+
formatMutationFailure
|
|
17
|
+
} from "#blokkli/agent/app/helpers/mutationResult";
|
|
15
18
|
import { mcpTools } from "#blokkli-build/agent-client";
|
|
16
19
|
import { itemEntityType } from "#blokkli-build/config";
|
|
17
20
|
import { generateId } from "#blokkli/agent/app/helpers/id";
|
|
@@ -95,14 +98,19 @@ export default function toolsProvider({
|
|
|
95
98
|
if (setLabel) setLabel(action.label);
|
|
96
99
|
async function applyMutation() {
|
|
97
100
|
const uuidsBefore = state.getAllUuids();
|
|
98
|
-
await state.
|
|
101
|
+
const response = await state.applyMutationSilently(
|
|
102
|
+
() => action.apply(adapter)
|
|
103
|
+
);
|
|
104
|
+
if (!response || !response.success) {
|
|
105
|
+
return { ok: false, error: formatMutationFailure(response) };
|
|
106
|
+
}
|
|
99
107
|
const newUuids = state.getAllUuids().filter((uuid) => !uuidsBefore.includes(uuid));
|
|
100
108
|
const selectUuids = newUuids.length ? newUuids : action.affectedUuids || [];
|
|
101
109
|
if (selectUuids.length) {
|
|
102
110
|
app.eventBus.emit("select", selectUuids);
|
|
103
111
|
app.eventBus.emit("scrollSelectionIntoView", {});
|
|
104
112
|
}
|
|
105
|
-
return newUuids;
|
|
113
|
+
return { ok: true, result: buildMutationResult(newUuids), meta: {} };
|
|
106
114
|
}
|
|
107
115
|
function buildMutationResult(newUuids) {
|
|
108
116
|
const newParagraphs = action.type === "add" ? buildNewParagraphsTree(newUuids, app, itemEntityType) : [];
|
|
@@ -114,13 +122,11 @@ export default function toolsProvider({
|
|
|
114
122
|
};
|
|
115
123
|
}
|
|
116
124
|
if (autoApprove.value || !toolDef.requiresApproval) {
|
|
117
|
-
|
|
118
|
-
return { ok: true, result: buildMutationResult(newUuids), meta: {} };
|
|
125
|
+
return applyMutation();
|
|
119
126
|
}
|
|
120
127
|
const approved = await waitForApproval(action);
|
|
121
128
|
if (approved) {
|
|
122
|
-
|
|
123
|
-
return { ok: true, result: buildMutationResult(newUuids), meta: {} };
|
|
129
|
+
return applyMutation();
|
|
124
130
|
}
|
|
125
131
|
if (action.revert) action.revert();
|
|
126
132
|
return { ok: true, result: { success: false, rejected: true }, meta: {} };
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
type OptionValue = string | boolean | number | string[];
|
|
3
|
+
/**
|
|
4
|
+
* The accepted input shapes for a single content-field value, mirroring
|
|
5
|
+
* `contentFieldValueSchema`. Normalized to `CanonicalFieldValue` before use.
|
|
6
|
+
*/
|
|
7
|
+
type ContentFieldInput = string | {
|
|
8
|
+
uri: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
} | {
|
|
11
|
+
entityType: string;
|
|
12
|
+
entityId: string;
|
|
13
|
+
} | {
|
|
14
|
+
target_id: string;
|
|
15
|
+
target_type?: string;
|
|
16
|
+
};
|
|
3
17
|
type BlockInput = {
|
|
4
18
|
bundle: string;
|
|
5
|
-
contentFields?: Record<string,
|
|
6
|
-
entityType: string;
|
|
7
|
-
entityId: string;
|
|
8
|
-
}>;
|
|
19
|
+
contentFields?: Record<string, ContentFieldInput>;
|
|
9
20
|
options?: Record<string, OptionValue>;
|
|
10
21
|
children?: Record<string, BlockInput[]>;
|
|
11
22
|
};
|
|
@@ -17,23 +17,48 @@ import { validateFieldCardinality } from "../../helpers/validation.js";
|
|
|
17
17
|
import { getFieldKey } from "#blokkli/helpers";
|
|
18
18
|
import { optionValueToStorable } from "#blokkli/editor/helpers/options";
|
|
19
19
|
import { countNewParagraphs } from "#blokkli/agent/app/helpers/mutationResult";
|
|
20
|
-
const contentFieldValueSchema = z.union(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
const contentFieldValueSchema = z.union(
|
|
21
|
+
[
|
|
22
|
+
z.string().describe(
|
|
23
|
+
"Text for plain/markup fields, or a URL/link URI (https://\u2026, mailto:, tel:, internal:/path, entity:type/id) for link fields."
|
|
24
|
+
),
|
|
25
|
+
z.object({
|
|
26
|
+
uri: z.string().describe("The link target: an absolute URL or a backend link URI."),
|
|
27
|
+
title: z.string().optional().describe(
|
|
28
|
+
"Optional link text. Accepted, but the URI is what gets stored \u2014 some backends do not persist the title yet."
|
|
29
|
+
)
|
|
30
|
+
}).describe("Link field value with an optional title."),
|
|
31
|
+
z.object({
|
|
32
|
+
entityType: z.string().describe('Entity type (e.g. "media", "node").'),
|
|
33
|
+
entityId: z.string().describe("Entity ID.")
|
|
34
|
+
}).describe(
|
|
35
|
+
"Entity reference for reference fields (media, content references), from search_media / search_content results."
|
|
36
|
+
),
|
|
37
|
+
z.object({
|
|
38
|
+
target_id: z.string().describe("The referenced entity ID."),
|
|
39
|
+
target_type: z.string().optional().describe("The referenced entity type, if known.")
|
|
40
|
+
}).describe(
|
|
41
|
+
"Entity reference in the backend-native { target_id } shape (equivalent to { entityType, entityId })."
|
|
42
|
+
)
|
|
43
|
+
],
|
|
44
|
+
{
|
|
45
|
+
error: "Content field value must be one of: a text/URL string; a link object { uri, title? }; or an entity reference { entityType, entityId } or { target_id, target_type? }."
|
|
46
|
+
}
|
|
47
|
+
);
|
|
31
48
|
const contentFieldsSchema = z.record(
|
|
32
49
|
z.string().describe("The content field name"),
|
|
33
50
|
contentFieldValueSchema
|
|
34
51
|
).optional().describe(
|
|
35
52
|
"Content field values to set on the new paragraph, keyed by field name. Use this to set text content and media/entity references in one step."
|
|
36
53
|
);
|
|
54
|
+
function normalizeContentFieldValue(value) {
|
|
55
|
+
if (typeof value === "string") return value;
|
|
56
|
+
if ("uri" in value) return value.uri;
|
|
57
|
+
if ("target_id" in value) {
|
|
58
|
+
return { entityType: value.target_type ?? "", entityId: value.target_id };
|
|
59
|
+
}
|
|
60
|
+
return { entityType: value.entityType, entityId: value.entityId };
|
|
61
|
+
}
|
|
37
62
|
const blockSchema = z.object({
|
|
38
63
|
bundle: z.string().describe("The paragraph bundle to add"),
|
|
39
64
|
contentFields: contentFieldsSchema,
|
|
@@ -54,7 +79,10 @@ export const paramsSchema = z.object({
|
|
|
54
79
|
});
|
|
55
80
|
function validateContentFields(ctx, block, path) {
|
|
56
81
|
if (!block.contentFields) return void 0;
|
|
57
|
-
for (const [fieldName,
|
|
82
|
+
for (const [fieldName, rawFieldValue] of Object.entries(
|
|
83
|
+
block.contentFields
|
|
84
|
+
)) {
|
|
85
|
+
const fieldValue = normalizeContentFieldValue(rawFieldValue);
|
|
58
86
|
const editableConfig = ctx.app.types.editableFieldConfig.forName(
|
|
59
87
|
ctx.itemEntityType,
|
|
60
88
|
block.bundle,
|
|
@@ -76,7 +104,7 @@ function validateContentFields(ctx, block, path) {
|
|
|
76
104
|
}
|
|
77
105
|
if (droppableConfig) {
|
|
78
106
|
if (typeof fieldValue === "string" && droppableConfig.type !== "link") {
|
|
79
|
-
return `${path}: Field "${fieldName}" is a reference field and expects { entityType, entityId }, got a string.`;
|
|
107
|
+
return `${path}: Field "${fieldName}" is a reference field and expects { entityType, entityId } (or { target_id }), got a string.`;
|
|
80
108
|
}
|
|
81
109
|
}
|
|
82
110
|
}
|
|
@@ -161,7 +189,7 @@ function buildEventBlocks(ctx, blocks, parentBundle) {
|
|
|
161
189
|
const blockUuid = generateUUID();
|
|
162
190
|
const values = block.contentFields ? Object.entries(block.contentFields).map(([fieldName, fieldValue]) => ({
|
|
163
191
|
fieldName,
|
|
164
|
-
fieldValue
|
|
192
|
+
fieldValue: normalizeContentFieldValue(fieldValue)
|
|
165
193
|
})) : void 0;
|
|
166
194
|
let options;
|
|
167
195
|
if (block.options) {
|
|
@@ -229,7 +257,7 @@ function collectAllUuids(blocks) {
|
|
|
229
257
|
export const resultSchema = mutationResultSchema;
|
|
230
258
|
export default defineBlokkliAgentTool({
|
|
231
259
|
name: "add_paragraphs",
|
|
232
|
-
description: "Add one or more new paragraphs to the page. Supports nested structures via the `children` property \u2014 define entire paragraph trees in a single call. IMPORTANT: Always provide content field values (text, media/entity references) directly via contentFields, instead of adding empty paragraphs! For reference content fields (media), set the value to { entityType, entityId } from search_media results. NOTE: You can ONLY provide content fields, NOT paragraph fields! For nested paragraphs, use the `children` property keyed by paragraph field name. You can also set paragraph options inline via the `options` property (key-value pairs). The success result mirrors the input shape: each top-level entry in `newParagraphs` includes its own `children` keyed by paragraph field, so the structure round-trips and a nested child does NOT appear as a sibling \u2014 treat the tree as the source of truth instead of guessing from order.",
|
|
260
|
+
description: "Add one or more new paragraphs to the page. Supports nested structures via the `children` property \u2014 define entire paragraph trees in a single call. IMPORTANT: Always provide content field values (text, media/entity references) directly via contentFields, instead of adding empty paragraphs! For reference content fields (media), set the value to { entityType, entityId } from search_media results. For link fields, set a URL string or { uri, title }. NOTE: You can ONLY provide content fields, NOT paragraph fields! For nested paragraphs, use the `children` property keyed by paragraph field name. You can also set paragraph options inline via the `options` property (key-value pairs). The success result mirrors the input shape: each top-level entry in `newParagraphs` includes its own `children` keyed by paragraph field, so the structure round-trips and a nested child does NOT appear as a sibling \u2014 treat the tree as the source of truth instead of guessing from order.",
|
|
233
261
|
category: "mutation",
|
|
234
262
|
lazy: false,
|
|
235
263
|
prunedSummary: (r) => r.success ? `added ${countNewParagraphs(r.newParagraphs ?? [])} paragraphs` : "rejected",
|
|
@@ -5,7 +5,9 @@ export default defineServerSideTool({
|
|
|
5
5
|
description: 'Load additional tools by name before using them. You must call this before using any tool listed under "Additional Tools" in the system prompt.',
|
|
6
6
|
inputSchema(ctx) {
|
|
7
7
|
return z.object({
|
|
8
|
-
tools: z.array(z.
|
|
8
|
+
tools: z.array(z.string()).describe(
|
|
9
|
+
ctx.lazyToolNames.length ? `Tool names to activate. Loadable tools: ${ctx.lazyToolNames.join(", ")}.` : "Tool names to activate."
|
|
10
|
+
)
|
|
9
11
|
});
|
|
10
12
|
},
|
|
11
13
|
isAvailable(ctx) {
|
package/dist/modules/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { b as Blokkli, B as BlokkliModule, d as defineBlokkliModule } from '../shared/editor.
|
|
1
|
+
export { b as Blokkli, B as BlokkliModule, d as defineBlokkliModule } from '../shared/editor.S5sA3rij.mjs';
|
|
2
2
|
import 'nuxt/schema';
|
|
3
3
|
import 'consola';
|
|
4
4
|
import '../../dist/global/types/definitions.js';
|
|
@@ -28,8 +28,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
28
28
|
onSubmit?: (() => any) | undefined;
|
|
29
29
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
|
-
minHeight: number;
|
|
32
31
|
maxHeight: number;
|
|
32
|
+
minHeight: number;
|
|
33
33
|
onBeforePaste: (data: ClipboardData) => boolean;
|
|
34
34
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
@@ -28,8 +28,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
28
28
|
onSubmit?: (() => any) | undefined;
|
|
29
29
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
|
-
minHeight: number;
|
|
32
31
|
maxHeight: number;
|
|
32
|
+
minHeight: number;
|
|
33
33
|
onBeforePaste: (data: ClipboardData) => boolean;
|
|
34
34
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
@@ -99,8 +99,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
99
99
|
disabled: boolean | string;
|
|
100
100
|
icon: BlokkliIcon;
|
|
101
101
|
active: boolean;
|
|
102
|
-
weight: number | string | "last";
|
|
103
102
|
tourText: string;
|
|
103
|
+
weight: number | string | "last";
|
|
104
104
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
105
105
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
106
106
|
declare const _default: typeof __VLS_export;
|
|
@@ -99,8 +99,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
99
99
|
disabled: boolean | string;
|
|
100
100
|
icon: BlokkliIcon;
|
|
101
101
|
active: boolean;
|
|
102
|
-
weight: number | string | "last";
|
|
103
102
|
tourText: string;
|
|
103
|
+
weight: number | string | "last";
|
|
104
104
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
105
105
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
106
106
|
declare const _default: typeof __VLS_export;
|
|
@@ -34,8 +34,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
34
34
|
width: number;
|
|
35
35
|
height: number;
|
|
36
36
|
};
|
|
37
|
-
minWidth: number;
|
|
38
37
|
minHeight: number;
|
|
38
|
+
minWidth: number;
|
|
39
39
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
40
40
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
41
41
|
declare const _default: typeof __VLS_export;
|
|
@@ -34,8 +34,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
34
34
|
width: number;
|
|
35
35
|
height: number;
|
|
36
36
|
};
|
|
37
|
-
minWidth: number;
|
|
38
37
|
minHeight: number;
|
|
38
|
+
minWidth: number;
|
|
39
39
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
40
40
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
41
41
|
declare const _default: typeof __VLS_export;
|
|
@@ -200,9 +200,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
200
200
|
width: number;
|
|
201
201
|
height: number;
|
|
202
202
|
};
|
|
203
|
-
tourText: string;
|
|
204
|
-
minWidth: number;
|
|
205
203
|
minHeight: number;
|
|
204
|
+
minWidth: number;
|
|
205
|
+
tourText: string;
|
|
206
206
|
region: SidebarRegion;
|
|
207
207
|
tooltipTitle: string;
|
|
208
208
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
@@ -200,9 +200,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
200
200
|
width: number;
|
|
201
201
|
height: number;
|
|
202
202
|
};
|
|
203
|
-
tourText: string;
|
|
204
|
-
minWidth: number;
|
|
205
203
|
minHeight: number;
|
|
204
|
+
minWidth: number;
|
|
205
|
+
tourText: string;
|
|
206
206
|
region: SidebarRegion;
|
|
207
207
|
tooltipTitle: string;
|
|
208
208
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Ref, type ComputedRef } from 'vue';
|
|
2
|
-
import type { BlokkliAdapter, AdapterContext } from '../adapter/index.js';
|
|
2
|
+
import type { BlokkliAdapter, AdapterContext, MutationResponseLike } from '../adapter/index.js';
|
|
3
3
|
import type { FieldListItem } from '#blokkli/types';
|
|
4
4
|
import { type BlokkliEventBus } from '#blokkli/editor/events';
|
|
5
5
|
import type { TextProvider } from './texts.js';
|
|
@@ -116,6 +116,22 @@ export type StateProvider = {
|
|
|
116
116
|
* response, or `null`/`undefined` to no-op.
|
|
117
117
|
*/
|
|
118
118
|
applyMutationState: (rawState: unknown) => void;
|
|
119
|
+
/**
|
|
120
|
+
* Run an adapter mutation with the loading lock, but return the raw response
|
|
121
|
+
* instead of a boolean and never emit an error toast.
|
|
122
|
+
*
|
|
123
|
+
* Like {@link mutateWithLoadingState} it locks the body for the duration of
|
|
124
|
+
* the call and applies any returned `state`, but it does NOT throw or show a
|
|
125
|
+
* global error message on failure. The caller receives the full
|
|
126
|
+
* {@link MutationResponseLike} and is responsible for surfacing violations —
|
|
127
|
+
* used by the agent tool runner, where the conversation UI already indicates
|
|
128
|
+
* that a tool errored and a global editor toast would be redundant.
|
|
129
|
+
*
|
|
130
|
+
* @param callback - Function that performs the mutation.
|
|
131
|
+
* @returns The raw mutation response, or `undefined` if no callback was
|
|
132
|
+
* provided or it resolved to no response.
|
|
133
|
+
*/
|
|
134
|
+
applyMutationSilently: (callback: () => Promise<MutationResponseLike<any>> | undefined) => Promise<MutationResponseLike<any> | undefined>;
|
|
119
135
|
/**
|
|
120
136
|
* Current edit mode.
|
|
121
137
|
*
|
|
@@ -319,6 +319,19 @@ export default async function(eventBus, adapter, context, $t, providerKey, permi
|
|
|
319
319
|
unlockBody();
|
|
320
320
|
return false;
|
|
321
321
|
};
|
|
322
|
+
const applyMutationSilently = async (callback) => {
|
|
323
|
+
if (!callback) {
|
|
324
|
+
return void 0;
|
|
325
|
+
}
|
|
326
|
+
lockBody();
|
|
327
|
+
try {
|
|
328
|
+
const response = await callback();
|
|
329
|
+
applyMutationState(response?.state);
|
|
330
|
+
return response;
|
|
331
|
+
} finally {
|
|
332
|
+
unlockBody();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
322
335
|
async function loadState() {
|
|
323
336
|
try {
|
|
324
337
|
const state = await adapter.loadState();
|
|
@@ -401,6 +414,7 @@ export default async function(eventBus, adapter, context, $t, providerKey, permi
|
|
|
401
414
|
lastChanged: readonly(lastChanged),
|
|
402
415
|
mutateWithLoadingState,
|
|
403
416
|
applyMutationState,
|
|
417
|
+
applyMutationSilently,
|
|
404
418
|
editMode,
|
|
405
419
|
canEdit,
|
|
406
420
|
isLoading: readonly(isLoading),
|
|
@@ -264,6 +264,11 @@ declare class ModuleHelper implements ValidationInterface {
|
|
|
264
264
|
* module and enabled sub-modules. Flushed by {@link applyBuildConfig}.
|
|
265
265
|
*/
|
|
266
266
|
private packageDependencies;
|
|
267
|
+
/**
|
|
268
|
+
* npm packages that must resolve to a single copy across the whole app.
|
|
269
|
+
* Flushed to Vite's resolve.dedupe by {@link applyBuildConfig}.
|
|
270
|
+
*/
|
|
271
|
+
private dedupedPackages;
|
|
267
272
|
readonly isDev: boolean;
|
|
268
273
|
readonly isModuleBuild: boolean;
|
|
269
274
|
readonly isPrepare: boolean;
|
|
@@ -305,11 +310,24 @@ declare class ModuleHelper implements ValidationInterface {
|
|
|
305
310
|
* @param names - Bare package specifiers (e.g. 'echarts', '@tiptap/core').
|
|
306
311
|
*/
|
|
307
312
|
addPackageDependency(...names: string[]): void;
|
|
313
|
+
/**
|
|
314
|
+
* Declare packages that must only ever exist once in the module graph.
|
|
315
|
+
*
|
|
316
|
+
* Libraries that rely on `instanceof` checks or module-level registries break
|
|
317
|
+
* when a project's install tree ends up with two copies (e.g. a hoisted
|
|
318
|
+
* version plus an older one nested under a transitive dependency). Forcing
|
|
319
|
+
* resolution to a single copy makes the editor work regardless of how the
|
|
320
|
+
* host project's package manager arranged node_modules.
|
|
321
|
+
*
|
|
322
|
+
* @param names - Bare package specifiers (e.g. 'prosemirror-model').
|
|
323
|
+
*/
|
|
324
|
+
addDedupedPackage(...names: string[]): void;
|
|
308
325
|
/**
|
|
309
326
|
* Apply collected build configuration to the Nuxt/Vite config.
|
|
310
327
|
*
|
|
311
328
|
* Called once by the core module after every module's setup has run, so it
|
|
312
|
-
* sees the full set of {@link addPackageDependency}
|
|
329
|
+
* sees the full set of {@link addPackageDependency} and
|
|
330
|
+
* {@link addDedupedPackage} registrations.
|
|
313
331
|
*/
|
|
314
332
|
applyBuildConfig(): void;
|
|
315
333
|
addAlias(name: string, path: string): void;
|
package/dist/types.d.mts
CHANGED
|
@@ -4,6 +4,6 @@ declare module '@nuxt/schema' {
|
|
|
4
4
|
interface NuxtHooks extends ModuleHooks {}
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export { type ModuleHooks } from './shared/editor.
|
|
7
|
+
export { type ModuleHooks } from './shared/editor.S5sA3rij.mjs'
|
|
8
8
|
|
|
9
9
|
export { type ModuleOptions, default } from './module.mjs'
|