@input/pen-core 0.1.7 → 0.1.9
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/index.cjs +190 -75
- package/dist/index.d.cts +72 -5
- package/dist/index.d.ts +72 -5
- package/dist/index.mjs +187 -75
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -134,6 +134,7 @@ __export(index_exports, {
|
|
|
134
134
|
historyUndo: () => historyUndo,
|
|
135
135
|
hookPriorityToPrecedence: () => hookPriorityToPrecedence,
|
|
136
136
|
indent: () => indent,
|
|
137
|
+
inlineLogicalText: () => inlineLogicalText,
|
|
137
138
|
inputRulesEngineFacet: () => inputRulesEngineFacet,
|
|
138
139
|
inputRulesFacet: () => inputRulesFacet,
|
|
139
140
|
insertLineBreak: () => insertLineBreak,
|
|
@@ -189,6 +190,7 @@ __export(index_exports, {
|
|
|
189
190
|
resolveSchema: () => resolveSchema,
|
|
190
191
|
resolveSchemaA11y: () => resolveSchemaA11y,
|
|
191
192
|
resolveSelectionTargetBlockIds: () => resolveSelectionTargetBlockIds,
|
|
193
|
+
resolveSuggestionMenuTarget: () => resolveSuggestionMenuTarget,
|
|
192
194
|
runMigrations: () => runMigrations,
|
|
193
195
|
searchControllerFacet: () => searchControllerFacet,
|
|
194
196
|
selectAdjacentInlineAtom: () => selectAdjacentInlineAtom,
|
|
@@ -206,6 +208,7 @@ __export(index_exports, {
|
|
|
206
208
|
shouldShowBlockInDefaultMenus: () => shouldShowBlockInDefaultMenus,
|
|
207
209
|
singleController: () => singleController,
|
|
208
210
|
slashMenuGroupOf: () => slashMenuGroupOf,
|
|
211
|
+
smoothStreamControllerFacet: () => smoothStreamControllerFacet,
|
|
209
212
|
snapToNormalPosition: () => snapToNormalPosition,
|
|
210
213
|
snapshotsControllerFacet: () => snapshotsControllerFacet,
|
|
211
214
|
sortDeltaAttributes: () => sortDeltaAttributes,
|
|
@@ -589,6 +592,47 @@ function filterOpsForDocumentProfile(ops, documentProfile, registry) {
|
|
|
589
592
|
};
|
|
590
593
|
}
|
|
591
594
|
|
|
595
|
+
// src/schema/generateValidator.ts
|
|
596
|
+
function generateValidator(propSchemas) {
|
|
597
|
+
return (raw) => {
|
|
598
|
+
const result = {};
|
|
599
|
+
for (const [key, schema] of Object.entries(propSchemas)) {
|
|
600
|
+
let value = raw[key];
|
|
601
|
+
if (value === void 0 || value === null) {
|
|
602
|
+
result[key] = schema.default;
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
const schemaType = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
606
|
+
if (schemaType === "number" && typeof value === "string") {
|
|
607
|
+
const parsed = Number(value);
|
|
608
|
+
if (!Number.isNaN(parsed)) value = parsed;
|
|
609
|
+
}
|
|
610
|
+
if (schemaType === "boolean" && typeof value === "string") {
|
|
611
|
+
value = value === "true";
|
|
612
|
+
}
|
|
613
|
+
const matchesSchemaType = schemaType === "array" ? Array.isArray(value) : typeof value === schemaType;
|
|
614
|
+
if (schema.type && schemaType !== void 0 && !matchesSchemaType) {
|
|
615
|
+
result[key] = schema.default;
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (typeof value === "number") {
|
|
619
|
+
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
620
|
+
value = schema.minimum;
|
|
621
|
+
}
|
|
622
|
+
if (typeof value === "number" && schema.maximum !== void 0 && value > schema.maximum) {
|
|
623
|
+
value = schema.maximum;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
627
|
+
result[key] = schema.default;
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
result[key] = value;
|
|
631
|
+
}
|
|
632
|
+
return result;
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
|
|
592
636
|
// src/schema/prop.ts
|
|
593
637
|
var PropChainImpl = class {
|
|
594
638
|
_schema;
|
|
@@ -895,6 +939,10 @@ var SchemaRegistryImpl = class _SchemaRegistryImpl {
|
|
|
895
939
|
if (patch.serialize) {
|
|
896
940
|
merged.serialize = { ...existing.serialize, ...patch.serialize };
|
|
897
941
|
}
|
|
942
|
+
if ("propSchema" in patch && !("validateProps" in patch)) {
|
|
943
|
+
const propSchema = merged.propSchema ?? {};
|
|
944
|
+
merged.validateProps = Object.keys(propSchema).length > 0 ? generateValidator(propSchema) : void 0;
|
|
945
|
+
}
|
|
898
946
|
const blocks = new Map(this._blocks);
|
|
899
947
|
blocks.set(type, merged);
|
|
900
948
|
return new _SchemaRegistryImpl({
|
|
@@ -989,45 +1037,6 @@ function generateAIDescription(type, props) {
|
|
|
989
1037
|
}).join(", ");
|
|
990
1038
|
return `${type}: ${propDescriptions}`;
|
|
991
1039
|
}
|
|
992
|
-
function generateValidator(propSchemas) {
|
|
993
|
-
return (raw) => {
|
|
994
|
-
const result = {};
|
|
995
|
-
for (const [key, schema] of Object.entries(propSchemas)) {
|
|
996
|
-
let value = raw[key];
|
|
997
|
-
if (value === void 0 || value === null) {
|
|
998
|
-
result[key] = schema.default;
|
|
999
|
-
continue;
|
|
1000
|
-
}
|
|
1001
|
-
const schemaType = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
1002
|
-
if (schemaType === "number" && typeof value === "string") {
|
|
1003
|
-
const parsed = Number(value);
|
|
1004
|
-
if (!Number.isNaN(parsed)) value = parsed;
|
|
1005
|
-
}
|
|
1006
|
-
if (schemaType === "boolean" && typeof value === "string") {
|
|
1007
|
-
value = value === "true";
|
|
1008
|
-
}
|
|
1009
|
-
const matchesSchemaType = schemaType === "array" ? Array.isArray(value) : typeof value === schemaType;
|
|
1010
|
-
if (schema.type && schemaType !== void 0 && !matchesSchemaType) {
|
|
1011
|
-
result[key] = schema.default;
|
|
1012
|
-
continue;
|
|
1013
|
-
}
|
|
1014
|
-
if (typeof value === "number") {
|
|
1015
|
-
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
1016
|
-
value = schema.minimum;
|
|
1017
|
-
}
|
|
1018
|
-
if (typeof value === "number" && schema.maximum !== void 0 && value > schema.maximum) {
|
|
1019
|
-
value = schema.maximum;
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
if (schema.enum && !schema.enum.includes(value)) {
|
|
1023
|
-
result[key] = schema.default;
|
|
1024
|
-
continue;
|
|
1025
|
-
}
|
|
1026
|
-
result[key] = value;
|
|
1027
|
-
}
|
|
1028
|
-
return result;
|
|
1029
|
-
};
|
|
1030
|
-
}
|
|
1031
1040
|
function defineBlock(typeOrConfig, maybeConfig) {
|
|
1032
1041
|
const type = typeof typeOrConfig === "string" ? typeOrConfig : typeOrConfig.type;
|
|
1033
1042
|
const config = typeof typeOrConfig === "string" ? maybeConfig : typeOrConfig;
|
|
@@ -3654,6 +3663,18 @@ function snapshotPlain(value) {
|
|
|
3654
3663
|
writable: true
|
|
3655
3664
|
});
|
|
3656
3665
|
}
|
|
3666
|
+
for (const key of Object.getOwnPropertySymbols(value)) {
|
|
3667
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
3668
|
+
if (!descriptor?.enumerable) {
|
|
3669
|
+
continue;
|
|
3670
|
+
}
|
|
3671
|
+
Object.defineProperty(next, key, {
|
|
3672
|
+
value: snapshotPlain(descriptor.value),
|
|
3673
|
+
enumerable: true,
|
|
3674
|
+
configurable: true,
|
|
3675
|
+
writable: true
|
|
3676
|
+
});
|
|
3677
|
+
}
|
|
3657
3678
|
return next;
|
|
3658
3679
|
}
|
|
3659
3680
|
function snapshotOps(ops) {
|
|
@@ -5087,17 +5108,54 @@ function normalizeFieldEditorType(schema) {
|
|
|
5087
5108
|
return "none";
|
|
5088
5109
|
}
|
|
5089
5110
|
|
|
5111
|
+
// src/editor/documentPreorder.ts
|
|
5112
|
+
function documentPreorderBlockIds(editor) {
|
|
5113
|
+
return documentPreorderBlockIdsFromState(editor.documentState);
|
|
5114
|
+
}
|
|
5115
|
+
function documentPreorderBlockIdsFromState(state) {
|
|
5116
|
+
const ids = [];
|
|
5117
|
+
for (const block of state.blocks) {
|
|
5118
|
+
ids.push(block.id);
|
|
5119
|
+
}
|
|
5120
|
+
return ids;
|
|
5121
|
+
}
|
|
5122
|
+
function documentPreorderBlockIdsFromDoc(doc) {
|
|
5123
|
+
const ids = [];
|
|
5124
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5125
|
+
const blocks = doc.blocks;
|
|
5126
|
+
const order = doc.blockOrder;
|
|
5127
|
+
const walk = (id) => {
|
|
5128
|
+
if (seen.has(id)) {
|
|
5129
|
+
return;
|
|
5130
|
+
}
|
|
5131
|
+
seen.add(id);
|
|
5132
|
+
ids.push(id);
|
|
5133
|
+
const blockMap = blocks.get(id);
|
|
5134
|
+
const children = blockMap?.get("children");
|
|
5135
|
+
if (!children) {
|
|
5136
|
+
return;
|
|
5137
|
+
}
|
|
5138
|
+
for (let i = 0; i < children.length; i++) {
|
|
5139
|
+
walk(children.get(i));
|
|
5140
|
+
}
|
|
5141
|
+
};
|
|
5142
|
+
for (let i = 0; i < order.length; i++) {
|
|
5143
|
+
walk(order.get(i));
|
|
5144
|
+
}
|
|
5145
|
+
return ids;
|
|
5146
|
+
}
|
|
5147
|
+
|
|
5090
5148
|
// src/editor/range.ts
|
|
5091
5149
|
var DocumentRangeImpl = class {
|
|
5092
5150
|
start;
|
|
5093
5151
|
end;
|
|
5094
5152
|
_anchor;
|
|
5095
5153
|
_focus;
|
|
5096
|
-
|
|
5154
|
+
_order;
|
|
5097
5155
|
constructor(anchor, focus, doc) {
|
|
5098
5156
|
this._anchor = anchor;
|
|
5099
5157
|
this._focus = focus;
|
|
5100
|
-
this.
|
|
5158
|
+
this._order = documentPreorderBlockIdsFromDoc(doc);
|
|
5101
5159
|
const anchorIdx = this._indexOfBlock(anchor.blockId);
|
|
5102
5160
|
const focusIdx = this._indexOfBlock(focus.blockId);
|
|
5103
5161
|
if (anchorIdx < focusIdx || anchorIdx === focusIdx && (anchor.offset ?? 0) <= (focus.offset ?? 0)) {
|
|
@@ -5126,13 +5184,10 @@ var DocumentRangeImpl = class {
|
|
|
5126
5184
|
get blockRange() {
|
|
5127
5185
|
const startIdx = this._indexOfBlock(this.start.blockId);
|
|
5128
5186
|
const endIdx = this._indexOfBlock(this.end.blockId);
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
result.push(
|
|
5132
|
-
this._doc.blockOrder.get(i)
|
|
5133
|
-
);
|
|
5187
|
+
if (startIdx < 0 || endIdx < 0) {
|
|
5188
|
+
return [];
|
|
5134
5189
|
}
|
|
5135
|
-
return
|
|
5190
|
+
return this._order.slice(startIdx, endIdx + 1);
|
|
5136
5191
|
}
|
|
5137
5192
|
contains(point) {
|
|
5138
5193
|
const idx = this._indexOfBlock(point.blockId);
|
|
@@ -5168,10 +5223,7 @@ var DocumentRangeImpl = class {
|
|
|
5168
5223
|
};
|
|
5169
5224
|
}
|
|
5170
5225
|
_indexOfBlock(blockId) {
|
|
5171
|
-
|
|
5172
|
-
if (this._doc.blockOrder.get(i) === blockId) return i;
|
|
5173
|
-
}
|
|
5174
|
-
return -1;
|
|
5226
|
+
return this._order.indexOf(blockId);
|
|
5175
5227
|
}
|
|
5176
5228
|
};
|
|
5177
5229
|
|
|
@@ -5235,13 +5287,10 @@ function blockIdsFromOrder(order, anchorId, focusId) {
|
|
|
5235
5287
|
);
|
|
5236
5288
|
}
|
|
5237
5289
|
function blockIdsBetween(doc, anchorId, focusId) {
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
indexOfBlock(order, anchorId),
|
|
5241
|
-
indexOfBlock(order, focusId),
|
|
5290
|
+
return blockIdsFromOrder(
|
|
5291
|
+
documentPreorderBlockIdsFromDoc(doc),
|
|
5242
5292
|
anchorId,
|
|
5243
|
-
focusId
|
|
5244
|
-
(index) => order.get(index)
|
|
5293
|
+
focusId
|
|
5245
5294
|
);
|
|
5246
5295
|
}
|
|
5247
5296
|
function sliceBlockIds(anchorIndex, focusIndex, anchorId, focusId, idAt) {
|
|
@@ -5262,14 +5311,6 @@ function sliceBlockIds(anchorIndex, focusIndex, anchorId, focusId, idAt) {
|
|
|
5262
5311
|
}
|
|
5263
5312
|
return ids;
|
|
5264
5313
|
}
|
|
5265
|
-
function indexOfBlock(order, blockId) {
|
|
5266
|
-
for (let i = 0; i < order.length; i++) {
|
|
5267
|
-
if (order.get(i) === blockId) {
|
|
5268
|
-
return i;
|
|
5269
|
-
}
|
|
5270
|
-
}
|
|
5271
|
-
return -1;
|
|
5272
|
-
}
|
|
5273
5314
|
|
|
5274
5315
|
// src/editor/anchorRepair.ts
|
|
5275
5316
|
function sitsInMovedRange(offset, assoc, range) {
|
|
@@ -7957,7 +7998,7 @@ function readTextAnchor(editor) {
|
|
|
7957
7998
|
return selection.anchor;
|
|
7958
7999
|
}
|
|
7959
8000
|
function documentOrderedTextPoints(editor, selection) {
|
|
7960
|
-
const order = editor
|
|
8001
|
+
const order = documentPreorderBlockIds(editor);
|
|
7961
8002
|
const anchorIndex = order.indexOf(selection.anchor.blockId);
|
|
7962
8003
|
const focusIndex = order.indexOf(selection.focus.blockId);
|
|
7963
8004
|
if (anchorIndex < 0 || focusIndex < 0) {
|
|
@@ -7971,7 +8012,7 @@ function documentOrderedTextPoints(editor, selection) {
|
|
|
7971
8012
|
|
|
7972
8013
|
// src/commands/commandSnapshots.ts
|
|
7973
8014
|
function buildNormalPositionSnapshot(editor) {
|
|
7974
|
-
const blockOrder = [...editor
|
|
8015
|
+
const blockOrder = [...getVisibleBlockIds(editor)];
|
|
7975
8016
|
const blocks = {};
|
|
7976
8017
|
for (const blockId of blockOrder) {
|
|
7977
8018
|
const block = editor.getBlock(blockId);
|
|
@@ -7992,7 +8033,7 @@ function buildNormalPositionSnapshot(editor) {
|
|
|
7992
8033
|
return { blockOrder, blocks };
|
|
7993
8034
|
}
|
|
7994
8035
|
function buildTransitionSnapshot(editor) {
|
|
7995
|
-
const blockOrder = [...editor
|
|
8036
|
+
const blockOrder = [...getVisibleBlockIds(editor)];
|
|
7996
8037
|
const blocks = {};
|
|
7997
8038
|
for (const blockId of blockOrder) {
|
|
7998
8039
|
const block = editor.getBlock(blockId);
|
|
@@ -8289,7 +8330,7 @@ function replaceSingleBlockRange(blockId, start, end, text, marks) {
|
|
|
8289
8330
|
};
|
|
8290
8331
|
}
|
|
8291
8332
|
function replaceMultiBlockRange(editor, start, end, text, marks) {
|
|
8292
|
-
const order = editor
|
|
8333
|
+
const order = documentPreorderBlockIds(editor);
|
|
8293
8334
|
const startIndex = order.indexOf(start.blockId);
|
|
8294
8335
|
const endIndex = order.indexOf(end.blockId);
|
|
8295
8336
|
if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex) {
|
|
@@ -8328,7 +8369,7 @@ function replaceMultiBlockRange(editor, start, end, text, marks) {
|
|
|
8328
8369
|
);
|
|
8329
8370
|
}
|
|
8330
8371
|
function replaceTextToTextRange(editor, start, end, text, marks, startIndex, endIndex, startLength) {
|
|
8331
|
-
const order = editor
|
|
8372
|
+
const order = documentPreorderBlockIds(editor);
|
|
8332
8373
|
const ops = [];
|
|
8333
8374
|
if (start.offset < startLength) {
|
|
8334
8375
|
ops.push(
|
|
@@ -8390,7 +8431,7 @@ function replaceTextToTextRange(editor, start, end, text, marks, startIndex, end
|
|
|
8390
8431
|
};
|
|
8391
8432
|
}
|
|
8392
8433
|
function replaceMixedBoundaryRange(editor, start, end, text, marks, startIndex, endIndex, startEditable, endEditable, startLength) {
|
|
8393
|
-
const order = editor
|
|
8434
|
+
const order = documentPreorderBlockIds(editor);
|
|
8394
8435
|
const ops = [];
|
|
8395
8436
|
if (startEditable) {
|
|
8396
8437
|
if (start.offset < startLength) {
|
|
@@ -9280,11 +9321,10 @@ var multiplayerControllerFacet = singleController(
|
|
|
9280
9321
|
);
|
|
9281
9322
|
var snapshotsControllerFacet = singleController("history.controller");
|
|
9282
9323
|
var assetProviderFacet = singleController("pen.assetProvider");
|
|
9283
|
-
var toolRuntimeFacet = singleController(
|
|
9284
|
-
"tools.toolRuntime"
|
|
9285
|
-
);
|
|
9324
|
+
var toolRuntimeFacet = singleController("tools.toolRuntime");
|
|
9286
9325
|
var announcerFacet = singleController("pen.announcer");
|
|
9287
9326
|
var streamingTargetFacet = singleController("deltaStream.target");
|
|
9327
|
+
var smoothStreamControllerFacet = singleController("ai.smoothStream");
|
|
9288
9328
|
|
|
9289
9329
|
// src/commands/history.ts
|
|
9290
9330
|
var historyUndo = defineCommand("history.undo");
|
|
@@ -10065,7 +10105,7 @@ function toggleMarkAcrossBlocks(editor, selection, param) {
|
|
|
10065
10105
|
if (!range) {
|
|
10066
10106
|
return false;
|
|
10067
10107
|
}
|
|
10068
|
-
const order = editor
|
|
10108
|
+
const order = documentPreorderBlockIds(editor);
|
|
10069
10109
|
const startIndex = order.indexOf(range.start.blockId);
|
|
10070
10110
|
const endIndex = order.indexOf(range.end.blockId);
|
|
10071
10111
|
if (startIndex < 0 || endIndex < 0) {
|
|
@@ -11076,6 +11116,7 @@ var FACET_BY_SLOT_KEY = {
|
|
|
11076
11116
|
"pen.messages": messagesFacet,
|
|
11077
11117
|
"pen.a11yLabel": a11yLabelFacet,
|
|
11078
11118
|
"delta-stream:target": streamingTargetFacet,
|
|
11119
|
+
"smooth-stream:controller": smoothStreamControllerFacet,
|
|
11079
11120
|
[import_pen_types7.ANNOUNCER_SLOT_KEY]: announcerFacet
|
|
11080
11121
|
};
|
|
11081
11122
|
function writeAssignedSlot(self, key, value) {
|
|
@@ -14475,6 +14516,77 @@ function emitMissingBlock(editor, blockId) {
|
|
|
14475
14516
|
emit("diagnostic", event);
|
|
14476
14517
|
}
|
|
14477
14518
|
|
|
14519
|
+
// src/suggestion/resolveSuggestionMenuTarget.ts
|
|
14520
|
+
var DEFAULT_LOOKBEHIND = 80;
|
|
14521
|
+
function inlineLogicalText(block) {
|
|
14522
|
+
return logicalInline(block).text;
|
|
14523
|
+
}
|
|
14524
|
+
function resolveSuggestionMenuTarget(editor, trigger) {
|
|
14525
|
+
if (trigger.char.length === 0) {
|
|
14526
|
+
return null;
|
|
14527
|
+
}
|
|
14528
|
+
const selection = editor.selection;
|
|
14529
|
+
if (selection?.type !== "text" || !isCollapsed(selection)) {
|
|
14530
|
+
return null;
|
|
14531
|
+
}
|
|
14532
|
+
if (selection.anchor.blockId !== selection.focus.blockId) {
|
|
14533
|
+
return null;
|
|
14534
|
+
}
|
|
14535
|
+
const block = editor.getBlock(selection.focus.blockId);
|
|
14536
|
+
if (!block) {
|
|
14537
|
+
return null;
|
|
14538
|
+
}
|
|
14539
|
+
const offset = selection.focus.offset;
|
|
14540
|
+
const lookbehind = trigger.lookbehind ?? DEFAULT_LOOKBEHIND;
|
|
14541
|
+
const prefixStartOffset = Math.max(0, offset - lookbehind);
|
|
14542
|
+
const { text, atoms } = logicalInline(block);
|
|
14543
|
+
const textBefore = text.slice(prefixStartOffset, offset);
|
|
14544
|
+
const triggerIndex = textBefore.lastIndexOf(trigger.char);
|
|
14545
|
+
if (triggerIndex < 0) {
|
|
14546
|
+
return null;
|
|
14547
|
+
}
|
|
14548
|
+
if (trigger.boundary === "whitespace") {
|
|
14549
|
+
const previousChar = textBefore[triggerIndex - 1];
|
|
14550
|
+
if (previousChar && !/\s/.test(previousChar)) {
|
|
14551
|
+
return null;
|
|
14552
|
+
}
|
|
14553
|
+
}
|
|
14554
|
+
const query = textBefore.slice(triggerIndex + trigger.char.length);
|
|
14555
|
+
const startOffset = prefixStartOffset + triggerIndex;
|
|
14556
|
+
const queryStartOffset = startOffset + trigger.char.length;
|
|
14557
|
+
if (queryRangeContainsAtom(atoms, queryStartOffset, offset)) {
|
|
14558
|
+
return null;
|
|
14559
|
+
}
|
|
14560
|
+
if (!trigger.allowSpaces && /\s/.test(query)) {
|
|
14561
|
+
return null;
|
|
14562
|
+
}
|
|
14563
|
+
if (trigger.closingChar && query.includes(trigger.closingChar)) {
|
|
14564
|
+
return null;
|
|
14565
|
+
}
|
|
14566
|
+
if (query.length < (trigger.minQueryLength ?? 0)) {
|
|
14567
|
+
return null;
|
|
14568
|
+
}
|
|
14569
|
+
if (trigger.maxQueryLength !== void 0 && query.length > trigger.maxQueryLength) {
|
|
14570
|
+
return null;
|
|
14571
|
+
}
|
|
14572
|
+
if (trigger.queryPattern) {
|
|
14573
|
+
trigger.queryPattern.lastIndex = 0;
|
|
14574
|
+
if (!trigger.queryPattern.test(query)) {
|
|
14575
|
+
return null;
|
|
14576
|
+
}
|
|
14577
|
+
}
|
|
14578
|
+
return {
|
|
14579
|
+
blockId: selection.focus.blockId,
|
|
14580
|
+
startOffset,
|
|
14581
|
+
endOffset: offset,
|
|
14582
|
+
query,
|
|
14583
|
+
trigger: trigger.char
|
|
14584
|
+
};
|
|
14585
|
+
}
|
|
14586
|
+
function queryRangeContainsAtom(atoms, queryStart, queryEnd) {
|
|
14587
|
+
return atoms.some((atom) => atom.start < queryEnd && atom.end > queryStart);
|
|
14588
|
+
}
|
|
14589
|
+
|
|
14478
14590
|
// src/commands/resolveDirectedBinding.ts
|
|
14479
14591
|
function resolveDirectedBinding(editor, binding) {
|
|
14480
14592
|
const direction = resolveFocusBlockDirection(editor);
|
|
@@ -15091,6 +15203,7 @@ function mapOffsetThroughSplices(splices, offset, assoc) {
|
|
|
15091
15203
|
historyUndo,
|
|
15092
15204
|
hookPriorityToPrecedence,
|
|
15093
15205
|
indent,
|
|
15206
|
+
inlineLogicalText,
|
|
15094
15207
|
inputRulesEngineFacet,
|
|
15095
15208
|
inputRulesFacet,
|
|
15096
15209
|
insertLineBreak,
|
|
@@ -15146,6 +15259,7 @@ function mapOffsetThroughSplices(splices, offset, assoc) {
|
|
|
15146
15259
|
resolveSchema,
|
|
15147
15260
|
resolveSchemaA11y,
|
|
15148
15261
|
resolveSelectionTargetBlockIds,
|
|
15262
|
+
resolveSuggestionMenuTarget,
|
|
15149
15263
|
runMigrations,
|
|
15150
15264
|
searchControllerFacet,
|
|
15151
15265
|
selectAdjacentInlineAtom,
|
|
@@ -15163,6 +15277,7 @@ function mapOffsetThroughSplices(splices, offset, assoc) {
|
|
|
15163
15277
|
shouldShowBlockInDefaultMenus,
|
|
15164
15278
|
singleController,
|
|
15165
15279
|
slashMenuGroupOf,
|
|
15280
|
+
smoothStreamControllerFacet,
|
|
15166
15281
|
snapToNormalPosition,
|
|
15167
15282
|
snapshotsControllerFacet,
|
|
15168
15283
|
sortDeltaAttributes,
|
package/dist/index.d.cts
CHANGED
|
@@ -304,7 +304,7 @@ declare class DocumentRangeImpl implements DocumentRange {
|
|
|
304
304
|
};
|
|
305
305
|
private readonly _anchor;
|
|
306
306
|
private readonly _focus;
|
|
307
|
-
private readonly
|
|
307
|
+
private readonly _order;
|
|
308
308
|
constructor(anchor: {
|
|
309
309
|
blockId: string;
|
|
310
310
|
offset?: number;
|
|
@@ -456,9 +456,10 @@ declare function createTextSelection(input: {
|
|
|
456
456
|
declare function isCollapsed(sel: ReadonlySelectionState): boolean;
|
|
457
457
|
declare function isMultiBlock(sel: ReadonlySelectionState): boolean;
|
|
458
458
|
/**
|
|
459
|
-
* Document-order block ids covered by `sel`.
|
|
460
|
-
*
|
|
461
|
-
* walking a live `Y.Array` through a
|
|
459
|
+
* Document-order block ids covered by `sel`. A live `PenDocument` walks
|
|
460
|
+
* nested `children` as well as top-level `blockOrder`. Pass a plain id
|
|
461
|
+
* snapshot from a renderer effect — walking a live `Y.Array` through a
|
|
462
|
+
* deep-proxied document writes back.
|
|
462
463
|
*/
|
|
463
464
|
declare function getSelectionBlockRange(doc: PenDocument | readonly string[], sel: ReadonlySelectionState): string[];
|
|
464
465
|
declare function isBlockSelected(blockOrder: readonly string[], sel: ReadonlySelectionState, blockId: string): boolean;
|
|
@@ -722,6 +723,71 @@ declare function resolveBlockDirection(editor: Editor, block: BlockHandle): Bloc
|
|
|
722
723
|
*/
|
|
723
724
|
declare function blockLogicalText(editor: Editor, blockId: string): string;
|
|
724
725
|
|
|
726
|
+
/** Whether a trigger may sit after a non-whitespace character. */
|
|
727
|
+
type SuggestionMenuBoundary = "any" | "whitespace";
|
|
728
|
+
/**
|
|
729
|
+
* Match constraints for {@link resolveSuggestionMenuTarget}.
|
|
730
|
+
*
|
|
731
|
+
* Offsets are logical (N6): each inline atom is one unit.
|
|
732
|
+
*/
|
|
733
|
+
interface SuggestionMenuTrigger {
|
|
734
|
+
/** Trigger string to find; empty `char` never matches. */
|
|
735
|
+
char: string;
|
|
736
|
+
/** Minimum query length after the trigger. @default 0 */
|
|
737
|
+
minQueryLength?: number;
|
|
738
|
+
/** Maximum query length after the trigger. @default unlimited */
|
|
739
|
+
maxQueryLength?: number;
|
|
740
|
+
/** How many logical offsets before the caret to search. @default 80 */
|
|
741
|
+
lookbehind?: number;
|
|
742
|
+
/** When false, a query containing whitespace is refused. @default false */
|
|
743
|
+
allowSpaces?: boolean;
|
|
744
|
+
/**
|
|
745
|
+
* `"whitespace"` requires start-of-prefix or a whitespace character before
|
|
746
|
+
* the trigger (an atom is not whitespace). `"any"` does not.
|
|
747
|
+
* @default "any"
|
|
748
|
+
*/
|
|
749
|
+
boundary?: SuggestionMenuBoundary;
|
|
750
|
+
/** When set, a query containing this character is refused. @default none */
|
|
751
|
+
closingChar?: string;
|
|
752
|
+
/** When set, the query must match; `lastIndex` is reset first. @default none */
|
|
753
|
+
queryPattern?: RegExp;
|
|
754
|
+
}
|
|
755
|
+
/** Resolved trigger range in the logical offset domain (N6). */
|
|
756
|
+
interface SuggestionMenuTarget {
|
|
757
|
+
blockId: string;
|
|
758
|
+
startOffset: number;
|
|
759
|
+
endOffset: number;
|
|
760
|
+
query: string;
|
|
761
|
+
trigger: string;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Logical inline text of a block: stored string text plus one U+FFFC per
|
|
765
|
+
* inline atom, in the same offset domain as caret offsets and
|
|
766
|
+
* `block.length()` (N6).
|
|
767
|
+
*
|
|
768
|
+
* @param block - Live block handle to read.
|
|
769
|
+
* @returns The logical string. Empty blocks return `""`.
|
|
770
|
+
* @throws Never.
|
|
771
|
+
*/
|
|
772
|
+
declare function inlineLogicalText(block: BlockHandle): string;
|
|
773
|
+
/**
|
|
774
|
+
* Resolves a collapsed caret to a suggestion-menu trigger range.
|
|
775
|
+
*
|
|
776
|
+
* Matching uses the logical offset domain (N6), not `block.textContent()`.
|
|
777
|
+
* Each inline atom occupies one offset (U+FFFC in {@link inlineLogicalText}).
|
|
778
|
+
* A query range that contains an atom is refused. A trigger immediately after
|
|
779
|
+
* an atom starts at the offset after that atom; `boundary: "whitespace"` still
|
|
780
|
+
* rejects when the preceding unit is the atom.
|
|
781
|
+
*
|
|
782
|
+
* @param editor - Editor whose collapsed text caret is read.
|
|
783
|
+
* @param trigger - Trigger character and match constraints. See
|
|
784
|
+
* {@link SuggestionMenuTrigger} for field defaults.
|
|
785
|
+
* @returns The trigger range in logical offsets, or `null` when the caret is
|
|
786
|
+
* not a collapsed in-block text selection or the prefix does not match.
|
|
787
|
+
* @throws Never. Non-matches return `null`.
|
|
788
|
+
*/
|
|
789
|
+
declare function resolveSuggestionMenuTarget(editor: Editor, trigger: SuggestionMenuTrigger): SuggestionMenuTarget | null;
|
|
790
|
+
|
|
725
791
|
type DefaultKeymapContext = "text" | "cell" | "block" | "any";
|
|
726
792
|
type KeymapPlatform = "macos" | "windows" | "linux";
|
|
727
793
|
interface DefaultKeymapBinding {
|
|
@@ -1036,6 +1102,7 @@ declare const assetProviderFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
|
1036
1102
|
declare const toolRuntimeFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1037
1103
|
declare const announcerFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1038
1104
|
declare const streamingTargetFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1105
|
+
declare const smoothStreamControllerFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1039
1106
|
|
|
1040
1107
|
declare function affectedBlockIdsFromSummary(summary: Pick<ChangeSummary, "blockText" | "structural">, documentOrder?: readonly string[]): string[];
|
|
1041
1108
|
|
|
@@ -1048,4 +1115,4 @@ declare function affectedBlockIdsFromSummary(summary: Pick<ChangeSummary, "block
|
|
|
1048
1115
|
*/
|
|
1049
1116
|
declare function mapOffsetThroughSplices(splices: readonly TextSplice[], offset: number, assoc: Assoc): number;
|
|
1050
1117
|
|
|
1051
|
-
export { A11Y_MISSING_LABEL_CODE, APPLY_STORM_CODE, APPLY_STORM_QUEUE_LIMIT, type BeforeApplyHook, type BlockDirection, type BlockDirectionResolver, type BlockDirectionSetting, type CaretMotionParam, type CellCaretFocus, type CellCaretWrite, type ClipboardHandler, type CommandDispatchContext, type CommandHandlerTable, type CommandRegistry, type ContentMove, type ConvertBlockParam, type CreateCommandRegistryOptions, type CreateFacetRegistryOptions, type CreateHeadlessEditorOptions, type DecorationSource, type DefaultKeymapBinding, type DefaultKeymapContext, type DefinedBlockSchema, type DeleteGranularity, type DeleteParam, type DocumentMigration, DocumentRangeImpl, type EditorA11yLabelAttrs, EventEmitter, ExtensionManagerImpl, type FacetRegistry, type FacetSettleInput, HOOK_PRIORITIES, type InsertTextParam, type Keymap, type KeymapPlatform, type MigrationReport, type NormalPositionSnapshot, PIPELINE_PHASES, PSEUDO_LOCALE_CLOSE, PSEUDO_LOCALE_OPEN, type PendingBlock, type PendingBlockImportPolicyViolation, type PendingBlockProfilePolicyViolation, type ProfilePolicyViolation, type SchemaA11yAttrs, type SchemaA11yKind, SchemaEngineImpl, type SchemaRegistryConfig, SchemaRegistryImpl, type SelectBlockParam, SelectionAuthorityImpl as SelectionAuthority, type StructureBlockParam, type ToggleMarkParam, type UrlContext, type UrlPolicy, type VerticalCaretDirection, type VerticalCaretMeasure, type VerticalCaretMeasureResult, type VerticalCaretPoint, type WordRange, a11yLabelFacet, affectedBlockIdsFromSummary, aiAutocompleteControllerFacet, aiControllerFacet, aiEgressExtension, aiEgressFacet, aiInlineCompletionFacet, aiInlineHistoryFacet, aiReviewControllerFacet, aiSuggestionsControllerFacet, announceEditorA11y, announcerFacet, applyDirectedBinding, applyMergeBlocks, applySplitBlock, ariaReadOnlyFacet, assetProviderFacet, beforeApplyFacet, blockDirectionFacet, blockLogicalText, blocksToOps, buildMergeBlocksRecipe, buildNormalPositionSnapshot, buildSplitBlockRecipe, buildTableChildren, builtinCommandHandlers, caretBlockEnd, caretBlockStart, caretDocEnd, caretDocStart, caretDown, caretLeft, caretLineEnd, caretLineStart, caretRight, caretUp, caretWordLeft, caretWordRight, clipboardFacet, collectEditorKeyBindings, collectToolExecutionOutput, commandHandler, commandsFacet, convertBlock, convertBlockOps, createAppHandle, createBlockHandle, createCommandRegistry, createDecorationSet, createDocumentSession, createEditor, createEmptySchema, createFacetRegistry, createHeadlessEditor, createImportResult, createMutationGroupMetadata, createPseudoLocaleCatalog, createTextSelection, decorationsFacet, deepEqual, defaultDirectionFacet, defaultKeymapBindings, defineBlock, defineCommand, defineExtension, defineFacet, delegatesToGridEditing, deleteAdjacentInlineAtom, deleteBackward, deleteBlock, deleteForward, deriveContentMoves, duplicateBlock, emptyDecorationSet, ensureInlineCompletionController, fieldEditorHostFacet, filterAIRequest, filterOpsForDocumentProfile, filterPendingBlocksForDocumentProfile, foldAndNormalize, getApplyOptionsGroupId, getBlockSelectionRoleFromSchema, getBlockSelectionRoleFromType, getCellCaretFocus, getCommandRegistry, getEditorSelectionRecord, getFlowCapabilityFromSchema, getFlowCapabilityFromType, getInlineCompletionController, getNumberedListItemValue, getOpOriginGroupId, getOpOriginType, getSelectionBlockRange, getVerticalCaretGoalX, getVerticalCaretMeasure, hasFieldEditorSurface, hasIndexedCellSelectionMetadata, historyRedo, historyUndo, hookPriorityToPrecedence, indent, inputRulesEngineFacet, inputRulesFacet, insertLineBreak, insertText, interpolateMessage, isBlockSelected, isCollapsed, isContainerBlock, isContainerBlockType, isContinuousTextFlowCapability, isMultiBlock, isPseudoLocaleText, keyBindingPriorityToPrecedence, keymapFacet, localeFacet, mapOffsetThroughSplices, mergeDecorationSets, mergeSchemas, messagesFacet, moveBlockDown, moveBlockUp, multiplayerControllerFacet, nextGraphemeBoundary, nextWordBoundary, normalizePendingBlocksForImport, orderSlashMenuItemsByGroup, outdent, previousGraphemeBoundary, previousWordBoundary, priorityToPrecedence, prop, renderSelectionTargetBlockText, renderSelectionTargetText, repairAnchor, reportPendingBlockImportViolations, reportPendingBlockProfileViolations, resolveA11yBlockTypeLabel, resolveA11ySpec, resolveBlockDirection, resolveBlockFlowCapability, resolveCellSelectionCoord, resolveCellSelectionMatrix, resolveDefaultKeymap, resolveDirectedBinding, resolveDirectedCommand, resolveEditorA11yLabel, resolveEditorMessage, resolveEditorSchema, resolveFieldEditorBehavior, resolveFieldEditorInputMode, resolveFocusBlockDirection, resolveMessage, resolveSchema, resolveSchemaA11y, resolveSelectionTargetBlockIds, runMigrations, searchControllerFacet, selectAdjacentInlineAtom, selectAll, selectBlock, selectionToRange, setCellCaretFocus, setVerticalCaretGoalX, setVerticalCaretMeasure, shouldAllowDirectBlockPaste, shouldAllowFlowInsertionInSlashMenu, shouldExposeBlockInTooling, shouldForceBlockScopedSelectAll, shouldRenderContainerChildren, shouldShowBlockInDefaultMenus, singleController, slashMenuGroupOf, snapToNormalPosition, snapshotsControllerFacet, sortDeltaAttributes, spliceDeleteOp, spliceInsertOp, splitBlock, streamThroughEgress, streamingTargetFacet, suggestion, supportsInlineInputRules, supportsInlineMarks, tableCellDown, tableCellNext, tableCellPrev, tableEscapeGrid, toPseudoLocaleText, toggleMark, toolRuntimeFacet, undoManagerFacet, undoMetadataControllerFacet, undoRestoreControllerFacet, urlPolicy, urlPolicyFacet, usesInlineTextSelection, wordRangeAt };
|
|
1118
|
+
export { A11Y_MISSING_LABEL_CODE, APPLY_STORM_CODE, APPLY_STORM_QUEUE_LIMIT, type BeforeApplyHook, type BlockDirection, type BlockDirectionResolver, type BlockDirectionSetting, type CaretMotionParam, type CellCaretFocus, type CellCaretWrite, type ClipboardHandler, type CommandDispatchContext, type CommandHandlerTable, type CommandRegistry, type ContentMove, type ConvertBlockParam, type CreateCommandRegistryOptions, type CreateFacetRegistryOptions, type CreateHeadlessEditorOptions, type DecorationSource, type DefaultKeymapBinding, type DefaultKeymapContext, type DefinedBlockSchema, type DeleteGranularity, type DeleteParam, type DocumentMigration, DocumentRangeImpl, type EditorA11yLabelAttrs, EventEmitter, ExtensionManagerImpl, type FacetRegistry, type FacetSettleInput, HOOK_PRIORITIES, type InsertTextParam, type Keymap, type KeymapPlatform, type MigrationReport, type NormalPositionSnapshot, PIPELINE_PHASES, PSEUDO_LOCALE_CLOSE, PSEUDO_LOCALE_OPEN, type PendingBlock, type PendingBlockImportPolicyViolation, type PendingBlockProfilePolicyViolation, type ProfilePolicyViolation, type SchemaA11yAttrs, type SchemaA11yKind, SchemaEngineImpl, type SchemaRegistryConfig, SchemaRegistryImpl, type SelectBlockParam, SelectionAuthorityImpl as SelectionAuthority, type StructureBlockParam, type SuggestionMenuBoundary, type SuggestionMenuTarget, type SuggestionMenuTrigger, type ToggleMarkParam, type UrlContext, type UrlPolicy, type VerticalCaretDirection, type VerticalCaretMeasure, type VerticalCaretMeasureResult, type VerticalCaretPoint, type WordRange, a11yLabelFacet, affectedBlockIdsFromSummary, aiAutocompleteControllerFacet, aiControllerFacet, aiEgressExtension, aiEgressFacet, aiInlineCompletionFacet, aiInlineHistoryFacet, aiReviewControllerFacet, aiSuggestionsControllerFacet, announceEditorA11y, announcerFacet, applyDirectedBinding, applyMergeBlocks, applySplitBlock, ariaReadOnlyFacet, assetProviderFacet, beforeApplyFacet, blockDirectionFacet, blockLogicalText, blocksToOps, buildMergeBlocksRecipe, buildNormalPositionSnapshot, buildSplitBlockRecipe, buildTableChildren, builtinCommandHandlers, caretBlockEnd, caretBlockStart, caretDocEnd, caretDocStart, caretDown, caretLeft, caretLineEnd, caretLineStart, caretRight, caretUp, caretWordLeft, caretWordRight, clipboardFacet, collectEditorKeyBindings, collectToolExecutionOutput, commandHandler, commandsFacet, convertBlock, convertBlockOps, createAppHandle, createBlockHandle, createCommandRegistry, createDecorationSet, createDocumentSession, createEditor, createEmptySchema, createFacetRegistry, createHeadlessEditor, createImportResult, createMutationGroupMetadata, createPseudoLocaleCatalog, createTextSelection, decorationsFacet, deepEqual, defaultDirectionFacet, defaultKeymapBindings, defineBlock, defineCommand, defineExtension, defineFacet, delegatesToGridEditing, deleteAdjacentInlineAtom, deleteBackward, deleteBlock, deleteForward, deriveContentMoves, duplicateBlock, emptyDecorationSet, ensureInlineCompletionController, fieldEditorHostFacet, filterAIRequest, filterOpsForDocumentProfile, filterPendingBlocksForDocumentProfile, foldAndNormalize, getApplyOptionsGroupId, getBlockSelectionRoleFromSchema, getBlockSelectionRoleFromType, getCellCaretFocus, getCommandRegistry, getEditorSelectionRecord, getFlowCapabilityFromSchema, getFlowCapabilityFromType, getInlineCompletionController, getNumberedListItemValue, getOpOriginGroupId, getOpOriginType, getSelectionBlockRange, getVerticalCaretGoalX, getVerticalCaretMeasure, hasFieldEditorSurface, hasIndexedCellSelectionMetadata, historyRedo, historyUndo, hookPriorityToPrecedence, indent, inlineLogicalText, inputRulesEngineFacet, inputRulesFacet, insertLineBreak, insertText, interpolateMessage, isBlockSelected, isCollapsed, isContainerBlock, isContainerBlockType, isContinuousTextFlowCapability, isMultiBlock, isPseudoLocaleText, keyBindingPriorityToPrecedence, keymapFacet, localeFacet, mapOffsetThroughSplices, mergeDecorationSets, mergeSchemas, messagesFacet, moveBlockDown, moveBlockUp, multiplayerControllerFacet, nextGraphemeBoundary, nextWordBoundary, normalizePendingBlocksForImport, orderSlashMenuItemsByGroup, outdent, previousGraphemeBoundary, previousWordBoundary, priorityToPrecedence, prop, renderSelectionTargetBlockText, renderSelectionTargetText, repairAnchor, reportPendingBlockImportViolations, reportPendingBlockProfileViolations, resolveA11yBlockTypeLabel, resolveA11ySpec, resolveBlockDirection, resolveBlockFlowCapability, resolveCellSelectionCoord, resolveCellSelectionMatrix, resolveDefaultKeymap, resolveDirectedBinding, resolveDirectedCommand, resolveEditorA11yLabel, resolveEditorMessage, resolveEditorSchema, resolveFieldEditorBehavior, resolveFieldEditorInputMode, resolveFocusBlockDirection, resolveMessage, resolveSchema, resolveSchemaA11y, resolveSelectionTargetBlockIds, resolveSuggestionMenuTarget, runMigrations, searchControllerFacet, selectAdjacentInlineAtom, selectAll, selectBlock, selectionToRange, setCellCaretFocus, setVerticalCaretGoalX, setVerticalCaretMeasure, shouldAllowDirectBlockPaste, shouldAllowFlowInsertionInSlashMenu, shouldExposeBlockInTooling, shouldForceBlockScopedSelectAll, shouldRenderContainerChildren, shouldShowBlockInDefaultMenus, singleController, slashMenuGroupOf, smoothStreamControllerFacet, snapToNormalPosition, snapshotsControllerFacet, sortDeltaAttributes, spliceDeleteOp, spliceInsertOp, splitBlock, streamThroughEgress, streamingTargetFacet, suggestion, supportsInlineInputRules, supportsInlineMarks, tableCellDown, tableCellNext, tableCellPrev, tableEscapeGrid, toPseudoLocaleText, toggleMark, toolRuntimeFacet, undoManagerFacet, undoMetadataControllerFacet, undoRestoreControllerFacet, urlPolicy, urlPolicyFacet, usesInlineTextSelection, wordRangeAt };
|
package/dist/index.d.ts
CHANGED
|
@@ -304,7 +304,7 @@ declare class DocumentRangeImpl implements DocumentRange {
|
|
|
304
304
|
};
|
|
305
305
|
private readonly _anchor;
|
|
306
306
|
private readonly _focus;
|
|
307
|
-
private readonly
|
|
307
|
+
private readonly _order;
|
|
308
308
|
constructor(anchor: {
|
|
309
309
|
blockId: string;
|
|
310
310
|
offset?: number;
|
|
@@ -456,9 +456,10 @@ declare function createTextSelection(input: {
|
|
|
456
456
|
declare function isCollapsed(sel: ReadonlySelectionState): boolean;
|
|
457
457
|
declare function isMultiBlock(sel: ReadonlySelectionState): boolean;
|
|
458
458
|
/**
|
|
459
|
-
* Document-order block ids covered by `sel`.
|
|
460
|
-
*
|
|
461
|
-
* walking a live `Y.Array` through a
|
|
459
|
+
* Document-order block ids covered by `sel`. A live `PenDocument` walks
|
|
460
|
+
* nested `children` as well as top-level `blockOrder`. Pass a plain id
|
|
461
|
+
* snapshot from a renderer effect — walking a live `Y.Array` through a
|
|
462
|
+
* deep-proxied document writes back.
|
|
462
463
|
*/
|
|
463
464
|
declare function getSelectionBlockRange(doc: PenDocument | readonly string[], sel: ReadonlySelectionState): string[];
|
|
464
465
|
declare function isBlockSelected(blockOrder: readonly string[], sel: ReadonlySelectionState, blockId: string): boolean;
|
|
@@ -722,6 +723,71 @@ declare function resolveBlockDirection(editor: Editor, block: BlockHandle): Bloc
|
|
|
722
723
|
*/
|
|
723
724
|
declare function blockLogicalText(editor: Editor, blockId: string): string;
|
|
724
725
|
|
|
726
|
+
/** Whether a trigger may sit after a non-whitespace character. */
|
|
727
|
+
type SuggestionMenuBoundary = "any" | "whitespace";
|
|
728
|
+
/**
|
|
729
|
+
* Match constraints for {@link resolveSuggestionMenuTarget}.
|
|
730
|
+
*
|
|
731
|
+
* Offsets are logical (N6): each inline atom is one unit.
|
|
732
|
+
*/
|
|
733
|
+
interface SuggestionMenuTrigger {
|
|
734
|
+
/** Trigger string to find; empty `char` never matches. */
|
|
735
|
+
char: string;
|
|
736
|
+
/** Minimum query length after the trigger. @default 0 */
|
|
737
|
+
minQueryLength?: number;
|
|
738
|
+
/** Maximum query length after the trigger. @default unlimited */
|
|
739
|
+
maxQueryLength?: number;
|
|
740
|
+
/** How many logical offsets before the caret to search. @default 80 */
|
|
741
|
+
lookbehind?: number;
|
|
742
|
+
/** When false, a query containing whitespace is refused. @default false */
|
|
743
|
+
allowSpaces?: boolean;
|
|
744
|
+
/**
|
|
745
|
+
* `"whitespace"` requires start-of-prefix or a whitespace character before
|
|
746
|
+
* the trigger (an atom is not whitespace). `"any"` does not.
|
|
747
|
+
* @default "any"
|
|
748
|
+
*/
|
|
749
|
+
boundary?: SuggestionMenuBoundary;
|
|
750
|
+
/** When set, a query containing this character is refused. @default none */
|
|
751
|
+
closingChar?: string;
|
|
752
|
+
/** When set, the query must match; `lastIndex` is reset first. @default none */
|
|
753
|
+
queryPattern?: RegExp;
|
|
754
|
+
}
|
|
755
|
+
/** Resolved trigger range in the logical offset domain (N6). */
|
|
756
|
+
interface SuggestionMenuTarget {
|
|
757
|
+
blockId: string;
|
|
758
|
+
startOffset: number;
|
|
759
|
+
endOffset: number;
|
|
760
|
+
query: string;
|
|
761
|
+
trigger: string;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Logical inline text of a block: stored string text plus one U+FFFC per
|
|
765
|
+
* inline atom, in the same offset domain as caret offsets and
|
|
766
|
+
* `block.length()` (N6).
|
|
767
|
+
*
|
|
768
|
+
* @param block - Live block handle to read.
|
|
769
|
+
* @returns The logical string. Empty blocks return `""`.
|
|
770
|
+
* @throws Never.
|
|
771
|
+
*/
|
|
772
|
+
declare function inlineLogicalText(block: BlockHandle): string;
|
|
773
|
+
/**
|
|
774
|
+
* Resolves a collapsed caret to a suggestion-menu trigger range.
|
|
775
|
+
*
|
|
776
|
+
* Matching uses the logical offset domain (N6), not `block.textContent()`.
|
|
777
|
+
* Each inline atom occupies one offset (U+FFFC in {@link inlineLogicalText}).
|
|
778
|
+
* A query range that contains an atom is refused. A trigger immediately after
|
|
779
|
+
* an atom starts at the offset after that atom; `boundary: "whitespace"` still
|
|
780
|
+
* rejects when the preceding unit is the atom.
|
|
781
|
+
*
|
|
782
|
+
* @param editor - Editor whose collapsed text caret is read.
|
|
783
|
+
* @param trigger - Trigger character and match constraints. See
|
|
784
|
+
* {@link SuggestionMenuTrigger} for field defaults.
|
|
785
|
+
* @returns The trigger range in logical offsets, or `null` when the caret is
|
|
786
|
+
* not a collapsed in-block text selection or the prefix does not match.
|
|
787
|
+
* @throws Never. Non-matches return `null`.
|
|
788
|
+
*/
|
|
789
|
+
declare function resolveSuggestionMenuTarget(editor: Editor, trigger: SuggestionMenuTrigger): SuggestionMenuTarget | null;
|
|
790
|
+
|
|
725
791
|
type DefaultKeymapContext = "text" | "cell" | "block" | "any";
|
|
726
792
|
type KeymapPlatform = "macos" | "windows" | "linux";
|
|
727
793
|
interface DefaultKeymapBinding {
|
|
@@ -1036,6 +1102,7 @@ declare const assetProviderFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
|
1036
1102
|
declare const toolRuntimeFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1037
1103
|
declare const announcerFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1038
1104
|
declare const streamingTargetFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1105
|
+
declare const smoothStreamControllerFacet: _input_pen_types.Facet<unknown, unknown>;
|
|
1039
1106
|
|
|
1040
1107
|
declare function affectedBlockIdsFromSummary(summary: Pick<ChangeSummary, "blockText" | "structural">, documentOrder?: readonly string[]): string[];
|
|
1041
1108
|
|
|
@@ -1048,4 +1115,4 @@ declare function affectedBlockIdsFromSummary(summary: Pick<ChangeSummary, "block
|
|
|
1048
1115
|
*/
|
|
1049
1116
|
declare function mapOffsetThroughSplices(splices: readonly TextSplice[], offset: number, assoc: Assoc): number;
|
|
1050
1117
|
|
|
1051
|
-
export { A11Y_MISSING_LABEL_CODE, APPLY_STORM_CODE, APPLY_STORM_QUEUE_LIMIT, type BeforeApplyHook, type BlockDirection, type BlockDirectionResolver, type BlockDirectionSetting, type CaretMotionParam, type CellCaretFocus, type CellCaretWrite, type ClipboardHandler, type CommandDispatchContext, type CommandHandlerTable, type CommandRegistry, type ContentMove, type ConvertBlockParam, type CreateCommandRegistryOptions, type CreateFacetRegistryOptions, type CreateHeadlessEditorOptions, type DecorationSource, type DefaultKeymapBinding, type DefaultKeymapContext, type DefinedBlockSchema, type DeleteGranularity, type DeleteParam, type DocumentMigration, DocumentRangeImpl, type EditorA11yLabelAttrs, EventEmitter, ExtensionManagerImpl, type FacetRegistry, type FacetSettleInput, HOOK_PRIORITIES, type InsertTextParam, type Keymap, type KeymapPlatform, type MigrationReport, type NormalPositionSnapshot, PIPELINE_PHASES, PSEUDO_LOCALE_CLOSE, PSEUDO_LOCALE_OPEN, type PendingBlock, type PendingBlockImportPolicyViolation, type PendingBlockProfilePolicyViolation, type ProfilePolicyViolation, type SchemaA11yAttrs, type SchemaA11yKind, SchemaEngineImpl, type SchemaRegistryConfig, SchemaRegistryImpl, type SelectBlockParam, SelectionAuthorityImpl as SelectionAuthority, type StructureBlockParam, type ToggleMarkParam, type UrlContext, type UrlPolicy, type VerticalCaretDirection, type VerticalCaretMeasure, type VerticalCaretMeasureResult, type VerticalCaretPoint, type WordRange, a11yLabelFacet, affectedBlockIdsFromSummary, aiAutocompleteControllerFacet, aiControllerFacet, aiEgressExtension, aiEgressFacet, aiInlineCompletionFacet, aiInlineHistoryFacet, aiReviewControllerFacet, aiSuggestionsControllerFacet, announceEditorA11y, announcerFacet, applyDirectedBinding, applyMergeBlocks, applySplitBlock, ariaReadOnlyFacet, assetProviderFacet, beforeApplyFacet, blockDirectionFacet, blockLogicalText, blocksToOps, buildMergeBlocksRecipe, buildNormalPositionSnapshot, buildSplitBlockRecipe, buildTableChildren, builtinCommandHandlers, caretBlockEnd, caretBlockStart, caretDocEnd, caretDocStart, caretDown, caretLeft, caretLineEnd, caretLineStart, caretRight, caretUp, caretWordLeft, caretWordRight, clipboardFacet, collectEditorKeyBindings, collectToolExecutionOutput, commandHandler, commandsFacet, convertBlock, convertBlockOps, createAppHandle, createBlockHandle, createCommandRegistry, createDecorationSet, createDocumentSession, createEditor, createEmptySchema, createFacetRegistry, createHeadlessEditor, createImportResult, createMutationGroupMetadata, createPseudoLocaleCatalog, createTextSelection, decorationsFacet, deepEqual, defaultDirectionFacet, defaultKeymapBindings, defineBlock, defineCommand, defineExtension, defineFacet, delegatesToGridEditing, deleteAdjacentInlineAtom, deleteBackward, deleteBlock, deleteForward, deriveContentMoves, duplicateBlock, emptyDecorationSet, ensureInlineCompletionController, fieldEditorHostFacet, filterAIRequest, filterOpsForDocumentProfile, filterPendingBlocksForDocumentProfile, foldAndNormalize, getApplyOptionsGroupId, getBlockSelectionRoleFromSchema, getBlockSelectionRoleFromType, getCellCaretFocus, getCommandRegistry, getEditorSelectionRecord, getFlowCapabilityFromSchema, getFlowCapabilityFromType, getInlineCompletionController, getNumberedListItemValue, getOpOriginGroupId, getOpOriginType, getSelectionBlockRange, getVerticalCaretGoalX, getVerticalCaretMeasure, hasFieldEditorSurface, hasIndexedCellSelectionMetadata, historyRedo, historyUndo, hookPriorityToPrecedence, indent, inputRulesEngineFacet, inputRulesFacet, insertLineBreak, insertText, interpolateMessage, isBlockSelected, isCollapsed, isContainerBlock, isContainerBlockType, isContinuousTextFlowCapability, isMultiBlock, isPseudoLocaleText, keyBindingPriorityToPrecedence, keymapFacet, localeFacet, mapOffsetThroughSplices, mergeDecorationSets, mergeSchemas, messagesFacet, moveBlockDown, moveBlockUp, multiplayerControllerFacet, nextGraphemeBoundary, nextWordBoundary, normalizePendingBlocksForImport, orderSlashMenuItemsByGroup, outdent, previousGraphemeBoundary, previousWordBoundary, priorityToPrecedence, prop, renderSelectionTargetBlockText, renderSelectionTargetText, repairAnchor, reportPendingBlockImportViolations, reportPendingBlockProfileViolations, resolveA11yBlockTypeLabel, resolveA11ySpec, resolveBlockDirection, resolveBlockFlowCapability, resolveCellSelectionCoord, resolveCellSelectionMatrix, resolveDefaultKeymap, resolveDirectedBinding, resolveDirectedCommand, resolveEditorA11yLabel, resolveEditorMessage, resolveEditorSchema, resolveFieldEditorBehavior, resolveFieldEditorInputMode, resolveFocusBlockDirection, resolveMessage, resolveSchema, resolveSchemaA11y, resolveSelectionTargetBlockIds, runMigrations, searchControllerFacet, selectAdjacentInlineAtom, selectAll, selectBlock, selectionToRange, setCellCaretFocus, setVerticalCaretGoalX, setVerticalCaretMeasure, shouldAllowDirectBlockPaste, shouldAllowFlowInsertionInSlashMenu, shouldExposeBlockInTooling, shouldForceBlockScopedSelectAll, shouldRenderContainerChildren, shouldShowBlockInDefaultMenus, singleController, slashMenuGroupOf, snapToNormalPosition, snapshotsControllerFacet, sortDeltaAttributes, spliceDeleteOp, spliceInsertOp, splitBlock, streamThroughEgress, streamingTargetFacet, suggestion, supportsInlineInputRules, supportsInlineMarks, tableCellDown, tableCellNext, tableCellPrev, tableEscapeGrid, toPseudoLocaleText, toggleMark, toolRuntimeFacet, undoManagerFacet, undoMetadataControllerFacet, undoRestoreControllerFacet, urlPolicy, urlPolicyFacet, usesInlineTextSelection, wordRangeAt };
|
|
1118
|
+
export { A11Y_MISSING_LABEL_CODE, APPLY_STORM_CODE, APPLY_STORM_QUEUE_LIMIT, type BeforeApplyHook, type BlockDirection, type BlockDirectionResolver, type BlockDirectionSetting, type CaretMotionParam, type CellCaretFocus, type CellCaretWrite, type ClipboardHandler, type CommandDispatchContext, type CommandHandlerTable, type CommandRegistry, type ContentMove, type ConvertBlockParam, type CreateCommandRegistryOptions, type CreateFacetRegistryOptions, type CreateHeadlessEditorOptions, type DecorationSource, type DefaultKeymapBinding, type DefaultKeymapContext, type DefinedBlockSchema, type DeleteGranularity, type DeleteParam, type DocumentMigration, DocumentRangeImpl, type EditorA11yLabelAttrs, EventEmitter, ExtensionManagerImpl, type FacetRegistry, type FacetSettleInput, HOOK_PRIORITIES, type InsertTextParam, type Keymap, type KeymapPlatform, type MigrationReport, type NormalPositionSnapshot, PIPELINE_PHASES, PSEUDO_LOCALE_CLOSE, PSEUDO_LOCALE_OPEN, type PendingBlock, type PendingBlockImportPolicyViolation, type PendingBlockProfilePolicyViolation, type ProfilePolicyViolation, type SchemaA11yAttrs, type SchemaA11yKind, SchemaEngineImpl, type SchemaRegistryConfig, SchemaRegistryImpl, type SelectBlockParam, SelectionAuthorityImpl as SelectionAuthority, type StructureBlockParam, type SuggestionMenuBoundary, type SuggestionMenuTarget, type SuggestionMenuTrigger, type ToggleMarkParam, type UrlContext, type UrlPolicy, type VerticalCaretDirection, type VerticalCaretMeasure, type VerticalCaretMeasureResult, type VerticalCaretPoint, type WordRange, a11yLabelFacet, affectedBlockIdsFromSummary, aiAutocompleteControllerFacet, aiControllerFacet, aiEgressExtension, aiEgressFacet, aiInlineCompletionFacet, aiInlineHistoryFacet, aiReviewControllerFacet, aiSuggestionsControllerFacet, announceEditorA11y, announcerFacet, applyDirectedBinding, applyMergeBlocks, applySplitBlock, ariaReadOnlyFacet, assetProviderFacet, beforeApplyFacet, blockDirectionFacet, blockLogicalText, blocksToOps, buildMergeBlocksRecipe, buildNormalPositionSnapshot, buildSplitBlockRecipe, buildTableChildren, builtinCommandHandlers, caretBlockEnd, caretBlockStart, caretDocEnd, caretDocStart, caretDown, caretLeft, caretLineEnd, caretLineStart, caretRight, caretUp, caretWordLeft, caretWordRight, clipboardFacet, collectEditorKeyBindings, collectToolExecutionOutput, commandHandler, commandsFacet, convertBlock, convertBlockOps, createAppHandle, createBlockHandle, createCommandRegistry, createDecorationSet, createDocumentSession, createEditor, createEmptySchema, createFacetRegistry, createHeadlessEditor, createImportResult, createMutationGroupMetadata, createPseudoLocaleCatalog, createTextSelection, decorationsFacet, deepEqual, defaultDirectionFacet, defaultKeymapBindings, defineBlock, defineCommand, defineExtension, defineFacet, delegatesToGridEditing, deleteAdjacentInlineAtom, deleteBackward, deleteBlock, deleteForward, deriveContentMoves, duplicateBlock, emptyDecorationSet, ensureInlineCompletionController, fieldEditorHostFacet, filterAIRequest, filterOpsForDocumentProfile, filterPendingBlocksForDocumentProfile, foldAndNormalize, getApplyOptionsGroupId, getBlockSelectionRoleFromSchema, getBlockSelectionRoleFromType, getCellCaretFocus, getCommandRegistry, getEditorSelectionRecord, getFlowCapabilityFromSchema, getFlowCapabilityFromType, getInlineCompletionController, getNumberedListItemValue, getOpOriginGroupId, getOpOriginType, getSelectionBlockRange, getVerticalCaretGoalX, getVerticalCaretMeasure, hasFieldEditorSurface, hasIndexedCellSelectionMetadata, historyRedo, historyUndo, hookPriorityToPrecedence, indent, inlineLogicalText, inputRulesEngineFacet, inputRulesFacet, insertLineBreak, insertText, interpolateMessage, isBlockSelected, isCollapsed, isContainerBlock, isContainerBlockType, isContinuousTextFlowCapability, isMultiBlock, isPseudoLocaleText, keyBindingPriorityToPrecedence, keymapFacet, localeFacet, mapOffsetThroughSplices, mergeDecorationSets, mergeSchemas, messagesFacet, moveBlockDown, moveBlockUp, multiplayerControllerFacet, nextGraphemeBoundary, nextWordBoundary, normalizePendingBlocksForImport, orderSlashMenuItemsByGroup, outdent, previousGraphemeBoundary, previousWordBoundary, priorityToPrecedence, prop, renderSelectionTargetBlockText, renderSelectionTargetText, repairAnchor, reportPendingBlockImportViolations, reportPendingBlockProfileViolations, resolveA11yBlockTypeLabel, resolveA11ySpec, resolveBlockDirection, resolveBlockFlowCapability, resolveCellSelectionCoord, resolveCellSelectionMatrix, resolveDefaultKeymap, resolveDirectedBinding, resolveDirectedCommand, resolveEditorA11yLabel, resolveEditorMessage, resolveEditorSchema, resolveFieldEditorBehavior, resolveFieldEditorInputMode, resolveFocusBlockDirection, resolveMessage, resolveSchema, resolveSchemaA11y, resolveSelectionTargetBlockIds, resolveSuggestionMenuTarget, runMigrations, searchControllerFacet, selectAdjacentInlineAtom, selectAll, selectBlock, selectionToRange, setCellCaretFocus, setVerticalCaretGoalX, setVerticalCaretMeasure, shouldAllowDirectBlockPaste, shouldAllowFlowInsertionInSlashMenu, shouldExposeBlockInTooling, shouldForceBlockScopedSelectAll, shouldRenderContainerChildren, shouldShowBlockInDefaultMenus, singleController, slashMenuGroupOf, smoothStreamControllerFacet, snapToNormalPosition, snapshotsControllerFacet, sortDeltaAttributes, spliceDeleteOp, spliceInsertOp, splitBlock, streamThroughEgress, streamingTargetFacet, suggestion, supportsInlineInputRules, supportsInlineMarks, tableCellDown, tableCellNext, tableCellPrev, tableEscapeGrid, toPseudoLocaleText, toggleMark, toolRuntimeFacet, undoManagerFacet, undoMetadataControllerFacet, undoRestoreControllerFacet, urlPolicy, urlPolicyFacet, usesInlineTextSelection, wordRangeAt };
|
package/dist/index.mjs
CHANGED
|
@@ -353,6 +353,47 @@ function filterOpsForDocumentProfile(ops, documentProfile, registry) {
|
|
|
353
353
|
};
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
+
// src/schema/generateValidator.ts
|
|
357
|
+
function generateValidator(propSchemas) {
|
|
358
|
+
return (raw) => {
|
|
359
|
+
const result = {};
|
|
360
|
+
for (const [key, schema] of Object.entries(propSchemas)) {
|
|
361
|
+
let value = raw[key];
|
|
362
|
+
if (value === void 0 || value === null) {
|
|
363
|
+
result[key] = schema.default;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const schemaType = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
367
|
+
if (schemaType === "number" && typeof value === "string") {
|
|
368
|
+
const parsed = Number(value);
|
|
369
|
+
if (!Number.isNaN(parsed)) value = parsed;
|
|
370
|
+
}
|
|
371
|
+
if (schemaType === "boolean" && typeof value === "string") {
|
|
372
|
+
value = value === "true";
|
|
373
|
+
}
|
|
374
|
+
const matchesSchemaType = schemaType === "array" ? Array.isArray(value) : typeof value === schemaType;
|
|
375
|
+
if (schema.type && schemaType !== void 0 && !matchesSchemaType) {
|
|
376
|
+
result[key] = schema.default;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (typeof value === "number") {
|
|
380
|
+
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
381
|
+
value = schema.minimum;
|
|
382
|
+
}
|
|
383
|
+
if (typeof value === "number" && schema.maximum !== void 0 && value > schema.maximum) {
|
|
384
|
+
value = schema.maximum;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
388
|
+
result[key] = schema.default;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
result[key] = value;
|
|
392
|
+
}
|
|
393
|
+
return result;
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
356
397
|
// src/schema/prop.ts
|
|
357
398
|
var PropChainImpl = class {
|
|
358
399
|
_schema;
|
|
@@ -659,6 +700,10 @@ var SchemaRegistryImpl = class _SchemaRegistryImpl {
|
|
|
659
700
|
if (patch.serialize) {
|
|
660
701
|
merged.serialize = { ...existing.serialize, ...patch.serialize };
|
|
661
702
|
}
|
|
703
|
+
if ("propSchema" in patch && !("validateProps" in patch)) {
|
|
704
|
+
const propSchema = merged.propSchema ?? {};
|
|
705
|
+
merged.validateProps = Object.keys(propSchema).length > 0 ? generateValidator(propSchema) : void 0;
|
|
706
|
+
}
|
|
662
707
|
const blocks = new Map(this._blocks);
|
|
663
708
|
blocks.set(type, merged);
|
|
664
709
|
return new _SchemaRegistryImpl({
|
|
@@ -753,45 +798,6 @@ function generateAIDescription(type, props) {
|
|
|
753
798
|
}).join(", ");
|
|
754
799
|
return `${type}: ${propDescriptions}`;
|
|
755
800
|
}
|
|
756
|
-
function generateValidator(propSchemas) {
|
|
757
|
-
return (raw) => {
|
|
758
|
-
const result = {};
|
|
759
|
-
for (const [key, schema] of Object.entries(propSchemas)) {
|
|
760
|
-
let value = raw[key];
|
|
761
|
-
if (value === void 0 || value === null) {
|
|
762
|
-
result[key] = schema.default;
|
|
763
|
-
continue;
|
|
764
|
-
}
|
|
765
|
-
const schemaType = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
766
|
-
if (schemaType === "number" && typeof value === "string") {
|
|
767
|
-
const parsed = Number(value);
|
|
768
|
-
if (!Number.isNaN(parsed)) value = parsed;
|
|
769
|
-
}
|
|
770
|
-
if (schemaType === "boolean" && typeof value === "string") {
|
|
771
|
-
value = value === "true";
|
|
772
|
-
}
|
|
773
|
-
const matchesSchemaType = schemaType === "array" ? Array.isArray(value) : typeof value === schemaType;
|
|
774
|
-
if (schema.type && schemaType !== void 0 && !matchesSchemaType) {
|
|
775
|
-
result[key] = schema.default;
|
|
776
|
-
continue;
|
|
777
|
-
}
|
|
778
|
-
if (typeof value === "number") {
|
|
779
|
-
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
780
|
-
value = schema.minimum;
|
|
781
|
-
}
|
|
782
|
-
if (typeof value === "number" && schema.maximum !== void 0 && value > schema.maximum) {
|
|
783
|
-
value = schema.maximum;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
if (schema.enum && !schema.enum.includes(value)) {
|
|
787
|
-
result[key] = schema.default;
|
|
788
|
-
continue;
|
|
789
|
-
}
|
|
790
|
-
result[key] = value;
|
|
791
|
-
}
|
|
792
|
-
return result;
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
801
|
function defineBlock(typeOrConfig, maybeConfig) {
|
|
796
802
|
const type = typeof typeOrConfig === "string" ? typeOrConfig : typeOrConfig.type;
|
|
797
803
|
const config = typeof typeOrConfig === "string" ? maybeConfig : typeOrConfig;
|
|
@@ -3422,6 +3428,18 @@ function snapshotPlain(value) {
|
|
|
3422
3428
|
writable: true
|
|
3423
3429
|
});
|
|
3424
3430
|
}
|
|
3431
|
+
for (const key of Object.getOwnPropertySymbols(value)) {
|
|
3432
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
3433
|
+
if (!descriptor?.enumerable) {
|
|
3434
|
+
continue;
|
|
3435
|
+
}
|
|
3436
|
+
Object.defineProperty(next, key, {
|
|
3437
|
+
value: snapshotPlain(descriptor.value),
|
|
3438
|
+
enumerable: true,
|
|
3439
|
+
configurable: true,
|
|
3440
|
+
writable: true
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3425
3443
|
return next;
|
|
3426
3444
|
}
|
|
3427
3445
|
function snapshotOps(ops) {
|
|
@@ -4855,17 +4873,54 @@ function normalizeFieldEditorType(schema) {
|
|
|
4855
4873
|
return "none";
|
|
4856
4874
|
}
|
|
4857
4875
|
|
|
4876
|
+
// src/editor/documentPreorder.ts
|
|
4877
|
+
function documentPreorderBlockIds(editor) {
|
|
4878
|
+
return documentPreorderBlockIdsFromState(editor.documentState);
|
|
4879
|
+
}
|
|
4880
|
+
function documentPreorderBlockIdsFromState(state) {
|
|
4881
|
+
const ids = [];
|
|
4882
|
+
for (const block of state.blocks) {
|
|
4883
|
+
ids.push(block.id);
|
|
4884
|
+
}
|
|
4885
|
+
return ids;
|
|
4886
|
+
}
|
|
4887
|
+
function documentPreorderBlockIdsFromDoc(doc) {
|
|
4888
|
+
const ids = [];
|
|
4889
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4890
|
+
const blocks = doc.blocks;
|
|
4891
|
+
const order = doc.blockOrder;
|
|
4892
|
+
const walk = (id) => {
|
|
4893
|
+
if (seen.has(id)) {
|
|
4894
|
+
return;
|
|
4895
|
+
}
|
|
4896
|
+
seen.add(id);
|
|
4897
|
+
ids.push(id);
|
|
4898
|
+
const blockMap = blocks.get(id);
|
|
4899
|
+
const children = blockMap?.get("children");
|
|
4900
|
+
if (!children) {
|
|
4901
|
+
return;
|
|
4902
|
+
}
|
|
4903
|
+
for (let i = 0; i < children.length; i++) {
|
|
4904
|
+
walk(children.get(i));
|
|
4905
|
+
}
|
|
4906
|
+
};
|
|
4907
|
+
for (let i = 0; i < order.length; i++) {
|
|
4908
|
+
walk(order.get(i));
|
|
4909
|
+
}
|
|
4910
|
+
return ids;
|
|
4911
|
+
}
|
|
4912
|
+
|
|
4858
4913
|
// src/editor/range.ts
|
|
4859
4914
|
var DocumentRangeImpl = class {
|
|
4860
4915
|
start;
|
|
4861
4916
|
end;
|
|
4862
4917
|
_anchor;
|
|
4863
4918
|
_focus;
|
|
4864
|
-
|
|
4919
|
+
_order;
|
|
4865
4920
|
constructor(anchor, focus, doc) {
|
|
4866
4921
|
this._anchor = anchor;
|
|
4867
4922
|
this._focus = focus;
|
|
4868
|
-
this.
|
|
4923
|
+
this._order = documentPreorderBlockIdsFromDoc(doc);
|
|
4869
4924
|
const anchorIdx = this._indexOfBlock(anchor.blockId);
|
|
4870
4925
|
const focusIdx = this._indexOfBlock(focus.blockId);
|
|
4871
4926
|
if (anchorIdx < focusIdx || anchorIdx === focusIdx && (anchor.offset ?? 0) <= (focus.offset ?? 0)) {
|
|
@@ -4894,13 +4949,10 @@ var DocumentRangeImpl = class {
|
|
|
4894
4949
|
get blockRange() {
|
|
4895
4950
|
const startIdx = this._indexOfBlock(this.start.blockId);
|
|
4896
4951
|
const endIdx = this._indexOfBlock(this.end.blockId);
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
result.push(
|
|
4900
|
-
this._doc.blockOrder.get(i)
|
|
4901
|
-
);
|
|
4952
|
+
if (startIdx < 0 || endIdx < 0) {
|
|
4953
|
+
return [];
|
|
4902
4954
|
}
|
|
4903
|
-
return
|
|
4955
|
+
return this._order.slice(startIdx, endIdx + 1);
|
|
4904
4956
|
}
|
|
4905
4957
|
contains(point) {
|
|
4906
4958
|
const idx = this._indexOfBlock(point.blockId);
|
|
@@ -4936,10 +4988,7 @@ var DocumentRangeImpl = class {
|
|
|
4936
4988
|
};
|
|
4937
4989
|
}
|
|
4938
4990
|
_indexOfBlock(blockId) {
|
|
4939
|
-
|
|
4940
|
-
if (this._doc.blockOrder.get(i) === blockId) return i;
|
|
4941
|
-
}
|
|
4942
|
-
return -1;
|
|
4991
|
+
return this._order.indexOf(blockId);
|
|
4943
4992
|
}
|
|
4944
4993
|
};
|
|
4945
4994
|
|
|
@@ -5003,13 +5052,10 @@ function blockIdsFromOrder(order, anchorId, focusId) {
|
|
|
5003
5052
|
);
|
|
5004
5053
|
}
|
|
5005
5054
|
function blockIdsBetween(doc, anchorId, focusId) {
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
indexOfBlock(order, anchorId),
|
|
5009
|
-
indexOfBlock(order, focusId),
|
|
5055
|
+
return blockIdsFromOrder(
|
|
5056
|
+
documentPreorderBlockIdsFromDoc(doc),
|
|
5010
5057
|
anchorId,
|
|
5011
|
-
focusId
|
|
5012
|
-
(index) => order.get(index)
|
|
5058
|
+
focusId
|
|
5013
5059
|
);
|
|
5014
5060
|
}
|
|
5015
5061
|
function sliceBlockIds(anchorIndex, focusIndex, anchorId, focusId, idAt) {
|
|
@@ -5030,14 +5076,6 @@ function sliceBlockIds(anchorIndex, focusIndex, anchorId, focusId, idAt) {
|
|
|
5030
5076
|
}
|
|
5031
5077
|
return ids;
|
|
5032
5078
|
}
|
|
5033
|
-
function indexOfBlock(order, blockId) {
|
|
5034
|
-
for (let i = 0; i < order.length; i++) {
|
|
5035
|
-
if (order.get(i) === blockId) {
|
|
5036
|
-
return i;
|
|
5037
|
-
}
|
|
5038
|
-
}
|
|
5039
|
-
return -1;
|
|
5040
|
-
}
|
|
5041
5079
|
|
|
5042
5080
|
// src/editor/anchorRepair.ts
|
|
5043
5081
|
function sitsInMovedRange(offset, assoc, range) {
|
|
@@ -7738,7 +7776,7 @@ function readTextAnchor(editor) {
|
|
|
7738
7776
|
return selection.anchor;
|
|
7739
7777
|
}
|
|
7740
7778
|
function documentOrderedTextPoints(editor, selection) {
|
|
7741
|
-
const order = editor
|
|
7779
|
+
const order = documentPreorderBlockIds(editor);
|
|
7742
7780
|
const anchorIndex = order.indexOf(selection.anchor.blockId);
|
|
7743
7781
|
const focusIndex = order.indexOf(selection.focus.blockId);
|
|
7744
7782
|
if (anchorIndex < 0 || focusIndex < 0) {
|
|
@@ -7752,7 +7790,7 @@ function documentOrderedTextPoints(editor, selection) {
|
|
|
7752
7790
|
|
|
7753
7791
|
// src/commands/commandSnapshots.ts
|
|
7754
7792
|
function buildNormalPositionSnapshot(editor) {
|
|
7755
|
-
const blockOrder = [...editor
|
|
7793
|
+
const blockOrder = [...getVisibleBlockIds(editor)];
|
|
7756
7794
|
const blocks = {};
|
|
7757
7795
|
for (const blockId of blockOrder) {
|
|
7758
7796
|
const block = editor.getBlock(blockId);
|
|
@@ -7773,7 +7811,7 @@ function buildNormalPositionSnapshot(editor) {
|
|
|
7773
7811
|
return { blockOrder, blocks };
|
|
7774
7812
|
}
|
|
7775
7813
|
function buildTransitionSnapshot(editor) {
|
|
7776
|
-
const blockOrder = [...editor
|
|
7814
|
+
const blockOrder = [...getVisibleBlockIds(editor)];
|
|
7777
7815
|
const blocks = {};
|
|
7778
7816
|
for (const blockId of blockOrder) {
|
|
7779
7817
|
const block = editor.getBlock(blockId);
|
|
@@ -8070,7 +8108,7 @@ function replaceSingleBlockRange(blockId, start, end, text, marks) {
|
|
|
8070
8108
|
};
|
|
8071
8109
|
}
|
|
8072
8110
|
function replaceMultiBlockRange(editor, start, end, text, marks) {
|
|
8073
|
-
const order = editor
|
|
8111
|
+
const order = documentPreorderBlockIds(editor);
|
|
8074
8112
|
const startIndex = order.indexOf(start.blockId);
|
|
8075
8113
|
const endIndex = order.indexOf(end.blockId);
|
|
8076
8114
|
if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex) {
|
|
@@ -8109,7 +8147,7 @@ function replaceMultiBlockRange(editor, start, end, text, marks) {
|
|
|
8109
8147
|
);
|
|
8110
8148
|
}
|
|
8111
8149
|
function replaceTextToTextRange(editor, start, end, text, marks, startIndex, endIndex, startLength) {
|
|
8112
|
-
const order = editor
|
|
8150
|
+
const order = documentPreorderBlockIds(editor);
|
|
8113
8151
|
const ops = [];
|
|
8114
8152
|
if (start.offset < startLength) {
|
|
8115
8153
|
ops.push(
|
|
@@ -8171,7 +8209,7 @@ function replaceTextToTextRange(editor, start, end, text, marks, startIndex, end
|
|
|
8171
8209
|
};
|
|
8172
8210
|
}
|
|
8173
8211
|
function replaceMixedBoundaryRange(editor, start, end, text, marks, startIndex, endIndex, startEditable, endEditable, startLength) {
|
|
8174
|
-
const order = editor
|
|
8212
|
+
const order = documentPreorderBlockIds(editor);
|
|
8175
8213
|
const ops = [];
|
|
8176
8214
|
if (startEditable) {
|
|
8177
8215
|
if (start.offset < startLength) {
|
|
@@ -9061,11 +9099,10 @@ var multiplayerControllerFacet = singleController(
|
|
|
9061
9099
|
);
|
|
9062
9100
|
var snapshotsControllerFacet = singleController("history.controller");
|
|
9063
9101
|
var assetProviderFacet = singleController("pen.assetProvider");
|
|
9064
|
-
var toolRuntimeFacet = singleController(
|
|
9065
|
-
"tools.toolRuntime"
|
|
9066
|
-
);
|
|
9102
|
+
var toolRuntimeFacet = singleController("tools.toolRuntime");
|
|
9067
9103
|
var announcerFacet = singleController("pen.announcer");
|
|
9068
9104
|
var streamingTargetFacet = singleController("deltaStream.target");
|
|
9105
|
+
var smoothStreamControllerFacet = singleController("ai.smoothStream");
|
|
9069
9106
|
|
|
9070
9107
|
// src/commands/history.ts
|
|
9071
9108
|
var historyUndo = defineCommand("history.undo");
|
|
@@ -9846,7 +9883,7 @@ function toggleMarkAcrossBlocks(editor, selection, param) {
|
|
|
9846
9883
|
if (!range) {
|
|
9847
9884
|
return false;
|
|
9848
9885
|
}
|
|
9849
|
-
const order = editor
|
|
9886
|
+
const order = documentPreorderBlockIds(editor);
|
|
9850
9887
|
const startIndex = order.indexOf(range.start.blockId);
|
|
9851
9888
|
const endIndex = order.indexOf(range.end.blockId);
|
|
9852
9889
|
if (startIndex < 0 || endIndex < 0) {
|
|
@@ -10873,6 +10910,7 @@ var FACET_BY_SLOT_KEY = {
|
|
|
10873
10910
|
"pen.messages": messagesFacet,
|
|
10874
10911
|
"pen.a11yLabel": a11yLabelFacet,
|
|
10875
10912
|
"delta-stream:target": streamingTargetFacet,
|
|
10913
|
+
"smooth-stream:controller": smoothStreamControllerFacet,
|
|
10876
10914
|
[ANNOUNCER_SLOT_KEY]: announcerFacet
|
|
10877
10915
|
};
|
|
10878
10916
|
function writeAssignedSlot(self, key, value) {
|
|
@@ -14288,6 +14326,77 @@ function emitMissingBlock(editor, blockId) {
|
|
|
14288
14326
|
emit("diagnostic", event);
|
|
14289
14327
|
}
|
|
14290
14328
|
|
|
14329
|
+
// src/suggestion/resolveSuggestionMenuTarget.ts
|
|
14330
|
+
var DEFAULT_LOOKBEHIND = 80;
|
|
14331
|
+
function inlineLogicalText(block) {
|
|
14332
|
+
return logicalInline(block).text;
|
|
14333
|
+
}
|
|
14334
|
+
function resolveSuggestionMenuTarget(editor, trigger) {
|
|
14335
|
+
if (trigger.char.length === 0) {
|
|
14336
|
+
return null;
|
|
14337
|
+
}
|
|
14338
|
+
const selection = editor.selection;
|
|
14339
|
+
if (selection?.type !== "text" || !isCollapsed(selection)) {
|
|
14340
|
+
return null;
|
|
14341
|
+
}
|
|
14342
|
+
if (selection.anchor.blockId !== selection.focus.blockId) {
|
|
14343
|
+
return null;
|
|
14344
|
+
}
|
|
14345
|
+
const block = editor.getBlock(selection.focus.blockId);
|
|
14346
|
+
if (!block) {
|
|
14347
|
+
return null;
|
|
14348
|
+
}
|
|
14349
|
+
const offset = selection.focus.offset;
|
|
14350
|
+
const lookbehind = trigger.lookbehind ?? DEFAULT_LOOKBEHIND;
|
|
14351
|
+
const prefixStartOffset = Math.max(0, offset - lookbehind);
|
|
14352
|
+
const { text, atoms } = logicalInline(block);
|
|
14353
|
+
const textBefore = text.slice(prefixStartOffset, offset);
|
|
14354
|
+
const triggerIndex = textBefore.lastIndexOf(trigger.char);
|
|
14355
|
+
if (triggerIndex < 0) {
|
|
14356
|
+
return null;
|
|
14357
|
+
}
|
|
14358
|
+
if (trigger.boundary === "whitespace") {
|
|
14359
|
+
const previousChar = textBefore[triggerIndex - 1];
|
|
14360
|
+
if (previousChar && !/\s/.test(previousChar)) {
|
|
14361
|
+
return null;
|
|
14362
|
+
}
|
|
14363
|
+
}
|
|
14364
|
+
const query = textBefore.slice(triggerIndex + trigger.char.length);
|
|
14365
|
+
const startOffset = prefixStartOffset + triggerIndex;
|
|
14366
|
+
const queryStartOffset = startOffset + trigger.char.length;
|
|
14367
|
+
if (queryRangeContainsAtom(atoms, queryStartOffset, offset)) {
|
|
14368
|
+
return null;
|
|
14369
|
+
}
|
|
14370
|
+
if (!trigger.allowSpaces && /\s/.test(query)) {
|
|
14371
|
+
return null;
|
|
14372
|
+
}
|
|
14373
|
+
if (trigger.closingChar && query.includes(trigger.closingChar)) {
|
|
14374
|
+
return null;
|
|
14375
|
+
}
|
|
14376
|
+
if (query.length < (trigger.minQueryLength ?? 0)) {
|
|
14377
|
+
return null;
|
|
14378
|
+
}
|
|
14379
|
+
if (trigger.maxQueryLength !== void 0 && query.length > trigger.maxQueryLength) {
|
|
14380
|
+
return null;
|
|
14381
|
+
}
|
|
14382
|
+
if (trigger.queryPattern) {
|
|
14383
|
+
trigger.queryPattern.lastIndex = 0;
|
|
14384
|
+
if (!trigger.queryPattern.test(query)) {
|
|
14385
|
+
return null;
|
|
14386
|
+
}
|
|
14387
|
+
}
|
|
14388
|
+
return {
|
|
14389
|
+
blockId: selection.focus.blockId,
|
|
14390
|
+
startOffset,
|
|
14391
|
+
endOffset: offset,
|
|
14392
|
+
query,
|
|
14393
|
+
trigger: trigger.char
|
|
14394
|
+
};
|
|
14395
|
+
}
|
|
14396
|
+
function queryRangeContainsAtom(atoms, queryStart, queryEnd) {
|
|
14397
|
+
return atoms.some((atom) => atom.start < queryEnd && atom.end > queryStart);
|
|
14398
|
+
}
|
|
14399
|
+
|
|
14291
14400
|
// src/commands/resolveDirectedBinding.ts
|
|
14292
14401
|
function resolveDirectedBinding(editor, binding) {
|
|
14293
14402
|
const direction = resolveFocusBlockDirection(editor);
|
|
@@ -14913,6 +15022,7 @@ export {
|
|
|
14913
15022
|
historyUndo,
|
|
14914
15023
|
hookPriorityToPrecedence,
|
|
14915
15024
|
indent,
|
|
15025
|
+
inlineLogicalText,
|
|
14916
15026
|
inputRulesEngineFacet,
|
|
14917
15027
|
inputRulesFacet,
|
|
14918
15028
|
insertLineBreak,
|
|
@@ -14968,6 +15078,7 @@ export {
|
|
|
14968
15078
|
resolveSchema,
|
|
14969
15079
|
resolveSchemaA11y,
|
|
14970
15080
|
resolveSelectionTargetBlockIds,
|
|
15081
|
+
resolveSuggestionMenuTarget,
|
|
14971
15082
|
runMigrations,
|
|
14972
15083
|
searchControllerFacet,
|
|
14973
15084
|
selectAdjacentInlineAtom,
|
|
@@ -14985,6 +15096,7 @@ export {
|
|
|
14985
15096
|
shouldShowBlockInDefaultMenus,
|
|
14986
15097
|
singleController,
|
|
14987
15098
|
slashMenuGroupOf,
|
|
15099
|
+
smoothStreamControllerFacet,
|
|
14988
15100
|
snapToNormalPosition,
|
|
14989
15101
|
snapshotsControllerFacet,
|
|
14990
15102
|
sortDeltaAttributes,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@input/pen-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Headless, extension-first editor engine for human-AI co-authoring",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/input-systems/pen#readme",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"sideEffects": false,
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@input/pen-yjs": "^0.1.
|
|
47
|
-
"@input/pen-types": "^0.1.
|
|
46
|
+
"@input/pen-yjs": "^0.1.9",
|
|
47
|
+
"@input/pen-types": "^0.1.9"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"tsup": "^8.4.0",
|