mindoodb-app-sdk 0.0.18 → 0.0.20
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/README.md +355 -4
- package/dist/chunk-QGM4M3NI.js +37 -0
- package/dist/index.d.ts +50 -3
- package/dist/index.js +221 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +3959 -7
- package/dist/{types-jzokkBX5.d.ts → types-CQt2ObMu.d.ts} +149 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import "./chunk-QGM4M3NI.js";
|
|
2
|
+
|
|
1
3
|
// src/attachmentPreview.ts
|
|
2
4
|
function canPreviewAttachment(fileName, mimeType) {
|
|
3
5
|
const normalizedMimeType = mimeType.toLowerCase();
|
|
@@ -726,6 +728,22 @@ var MindooDBAppDatabaseImpl = class {
|
|
|
726
728
|
databaseId: this.databaseId,
|
|
727
729
|
docId
|
|
728
730
|
}),
|
|
731
|
+
getRichText: async (docId, path, options) => await this.rpc.call("documents.richText.get", {
|
|
732
|
+
databaseId: this.databaseId,
|
|
733
|
+
docId,
|
|
734
|
+
path,
|
|
735
|
+
revisionId: options?.revisionId
|
|
736
|
+
}),
|
|
737
|
+
getAutomergeSnapshot: async (docId, options) => await this.rpc.call("documents.automerge.getSnapshot", {
|
|
738
|
+
databaseId: this.databaseId,
|
|
739
|
+
docId,
|
|
740
|
+
revisionId: options?.revisionId
|
|
741
|
+
}),
|
|
742
|
+
applyAutomergeChanges: async (docId, patch) => await this.rpc.call("documents.automerge.applyChanges", {
|
|
743
|
+
databaseId: this.databaseId,
|
|
744
|
+
docId,
|
|
745
|
+
patch
|
|
746
|
+
}),
|
|
729
747
|
create: async (input) => await this.rpc.call("documents.create", {
|
|
730
748
|
databaseId: this.databaseId,
|
|
731
749
|
input
|
|
@@ -987,6 +1005,205 @@ function createMindooDBAppBridge() {
|
|
|
987
1005
|
};
|
|
988
1006
|
}
|
|
989
1007
|
|
|
1008
|
+
// src/richTextHandle.ts
|
|
1009
|
+
var MindooDBRichTextHandle = class {
|
|
1010
|
+
constructor(options) {
|
|
1011
|
+
this.options = options;
|
|
1012
|
+
const initialSpans = cloneSpans(options.spans ?? []);
|
|
1013
|
+
this.spansInternal = initialSpans;
|
|
1014
|
+
this.baseMaterializedText = readMaterializedRichTextText(
|
|
1015
|
+
options.document.data,
|
|
1016
|
+
options.path,
|
|
1017
|
+
initialSpans
|
|
1018
|
+
);
|
|
1019
|
+
this.heads = options.document.heads ? [...options.document.heads] : [];
|
|
1020
|
+
}
|
|
1021
|
+
options;
|
|
1022
|
+
spansInternal;
|
|
1023
|
+
baseMaterializedText;
|
|
1024
|
+
heads;
|
|
1025
|
+
dirtyInternal = false;
|
|
1026
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1027
|
+
pollTimer = null;
|
|
1028
|
+
get spans() {
|
|
1029
|
+
return cloneSpans(this.spansInternal);
|
|
1030
|
+
}
|
|
1031
|
+
get dirty() {
|
|
1032
|
+
return this.dirtyInternal;
|
|
1033
|
+
}
|
|
1034
|
+
get baseHeads() {
|
|
1035
|
+
return [...this.heads];
|
|
1036
|
+
}
|
|
1037
|
+
on(event, listener) {
|
|
1038
|
+
this.listeners.add(listener);
|
|
1039
|
+
}
|
|
1040
|
+
off(event, listener) {
|
|
1041
|
+
this.listeners.delete(listener);
|
|
1042
|
+
}
|
|
1043
|
+
replaceSpans(spans) {
|
|
1044
|
+
this.spansInternal = cloneSpans(spans);
|
|
1045
|
+
this.dirtyInternal = true;
|
|
1046
|
+
this.emitChange();
|
|
1047
|
+
}
|
|
1048
|
+
startPolling(intervalMs = this.options.pollIntervalMs ?? 2e3) {
|
|
1049
|
+
this.stopPolling();
|
|
1050
|
+
this.pollTimer = setInterval(() => {
|
|
1051
|
+
void this.pollOnce();
|
|
1052
|
+
}, intervalMs);
|
|
1053
|
+
}
|
|
1054
|
+
stopPolling() {
|
|
1055
|
+
if (this.pollTimer) {
|
|
1056
|
+
clearInterval(this.pollTimer);
|
|
1057
|
+
this.pollTimer = null;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
reconcile(document, snapshot) {
|
|
1061
|
+
const previous = JSON.stringify(this.spansInternal);
|
|
1062
|
+
this.spansInternal = cloneSpans(snapshot.spans);
|
|
1063
|
+
this.baseMaterializedText = spansToPlainText(snapshot.spans);
|
|
1064
|
+
this.heads = snapshot.heads ?? document.heads ?? [];
|
|
1065
|
+
this.dirtyInternal = false;
|
|
1066
|
+
const changed = JSON.stringify(this.spansInternal) !== previous;
|
|
1067
|
+
if (changed) {
|
|
1068
|
+
this.emitChange();
|
|
1069
|
+
}
|
|
1070
|
+
return changed;
|
|
1071
|
+
}
|
|
1072
|
+
async refresh() {
|
|
1073
|
+
const snapshot = await this.options.database.documents.getRichText(
|
|
1074
|
+
this.options.document.id,
|
|
1075
|
+
this.options.path
|
|
1076
|
+
);
|
|
1077
|
+
return snapshot;
|
|
1078
|
+
}
|
|
1079
|
+
async pollOnce() {
|
|
1080
|
+
if (this.dirtyInternal) {
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
const document = await this.options.database.documents.get(
|
|
1084
|
+
this.options.document.id
|
|
1085
|
+
);
|
|
1086
|
+
if (!document) {
|
|
1087
|
+
return false;
|
|
1088
|
+
}
|
|
1089
|
+
const snapshot = await this.refresh();
|
|
1090
|
+
return this.reconcile(document, snapshot);
|
|
1091
|
+
}
|
|
1092
|
+
async flush(updateSpansConfig) {
|
|
1093
|
+
if (!this.dirtyInternal) {
|
|
1094
|
+
return {
|
|
1095
|
+
document: this.options.document,
|
|
1096
|
+
snapshot: {
|
|
1097
|
+
path: [...this.options.path],
|
|
1098
|
+
heads: [...this.heads],
|
|
1099
|
+
spans: cloneSpans(this.spansInternal)
|
|
1100
|
+
},
|
|
1101
|
+
reconciled: false
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
const localSpansAtFlush = cloneSpans(this.spansInternal);
|
|
1105
|
+
const localTextAtFlush = spansToPlainText(localSpansAtFlush);
|
|
1106
|
+
const textChanged = localTextAtFlush !== this.baseMaterializedText;
|
|
1107
|
+
const document = textChanged ? await this.flushTextSteps(localTextAtFlush) : await this.options.database.documents.update(
|
|
1108
|
+
this.options.document.id,
|
|
1109
|
+
{
|
|
1110
|
+
richText: [{
|
|
1111
|
+
path: this.options.path,
|
|
1112
|
+
baseHeads: this.heads,
|
|
1113
|
+
spans: localSpansAtFlush,
|
|
1114
|
+
updateSpansConfig
|
|
1115
|
+
}]
|
|
1116
|
+
}
|
|
1117
|
+
);
|
|
1118
|
+
const snapshot = await this.options.database.documents.getRichText(
|
|
1119
|
+
this.options.document.id,
|
|
1120
|
+
this.options.path
|
|
1121
|
+
);
|
|
1122
|
+
const reconciled = JSON.stringify(snapshot.spans) !== JSON.stringify(localSpansAtFlush);
|
|
1123
|
+
this.spansInternal = cloneSpans(snapshot.spans);
|
|
1124
|
+
this.baseMaterializedText = spansToPlainText(snapshot.spans);
|
|
1125
|
+
this.heads = snapshot.heads ?? document.heads ?? [];
|
|
1126
|
+
this.dirtyInternal = false;
|
|
1127
|
+
if (reconciled) {
|
|
1128
|
+
this.emitChange();
|
|
1129
|
+
}
|
|
1130
|
+
return {
|
|
1131
|
+
document,
|
|
1132
|
+
snapshot,
|
|
1133
|
+
reconciled
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
async flushTextSteps(localTextAtFlush) {
|
|
1137
|
+
const edit = computeSingleSplice(this.baseMaterializedText, localTextAtFlush);
|
|
1138
|
+
return this.options.database.documents.update(this.options.document.id, {
|
|
1139
|
+
richTextSteps: [{
|
|
1140
|
+
path: this.options.path,
|
|
1141
|
+
baseHeads: this.heads,
|
|
1142
|
+
steps: [{
|
|
1143
|
+
type: "splice",
|
|
1144
|
+
index: edit.index,
|
|
1145
|
+
deleteCount: edit.deleteCount,
|
|
1146
|
+
insert: edit.insert ?? ""
|
|
1147
|
+
}]
|
|
1148
|
+
}]
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
emitChange() {
|
|
1152
|
+
const snapshot = {
|
|
1153
|
+
path: [...this.options.path],
|
|
1154
|
+
heads: [...this.heads],
|
|
1155
|
+
spans: cloneSpans(this.spansInternal)
|
|
1156
|
+
};
|
|
1157
|
+
for (const listener of this.listeners) {
|
|
1158
|
+
listener(snapshot);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
function createMindooDBRichTextHandle(options) {
|
|
1163
|
+
return new MindooDBRichTextHandle(options);
|
|
1164
|
+
}
|
|
1165
|
+
function cloneSpans(spans) {
|
|
1166
|
+
return structuredClone(spans);
|
|
1167
|
+
}
|
|
1168
|
+
function spansToPlainText(spans) {
|
|
1169
|
+
return spans.filter((span) => span.type === "text").map((span) => span.type === "text" ? span.value : "").join("");
|
|
1170
|
+
}
|
|
1171
|
+
function readMaterializedRichTextText(data, path, fallbackSpans) {
|
|
1172
|
+
let value = data;
|
|
1173
|
+
for (const segment of path) {
|
|
1174
|
+
if (value == null || typeof value !== "object") {
|
|
1175
|
+
return spansToPlainText(fallbackSpans);
|
|
1176
|
+
}
|
|
1177
|
+
value = value[segment];
|
|
1178
|
+
}
|
|
1179
|
+
if (typeof value === "string") {
|
|
1180
|
+
return value.replace(/\uFFFC/g, "");
|
|
1181
|
+
}
|
|
1182
|
+
if (Array.isArray(value)) {
|
|
1183
|
+
return spansToPlainText(value);
|
|
1184
|
+
}
|
|
1185
|
+
return spansToPlainText(fallbackSpans);
|
|
1186
|
+
}
|
|
1187
|
+
function computeSingleSplice(previous, next) {
|
|
1188
|
+
let prefixLength = 0;
|
|
1189
|
+
const maxPrefix = Math.min(previous.length, next.length);
|
|
1190
|
+
while (prefixLength < maxPrefix && previous[prefixLength] === next[prefixLength]) {
|
|
1191
|
+
prefixLength += 1;
|
|
1192
|
+
}
|
|
1193
|
+
let suffixLength = 0;
|
|
1194
|
+
const previousRemaining = previous.length - prefixLength;
|
|
1195
|
+
const nextRemaining = next.length - prefixLength;
|
|
1196
|
+
const maxSuffix = Math.min(previousRemaining, nextRemaining);
|
|
1197
|
+
while (suffixLength < maxSuffix && previous[previous.length - 1 - suffixLength] === next[next.length - 1 - suffixLength]) {
|
|
1198
|
+
suffixLength += 1;
|
|
1199
|
+
}
|
|
1200
|
+
return {
|
|
1201
|
+
index: prefixLength,
|
|
1202
|
+
deleteCount: previous.length - prefixLength - suffixLength,
|
|
1203
|
+
insert: next.slice(prefixLength, next.length - suffixLength)
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
|
|
990
1207
|
// src/textBuffer.ts
|
|
991
1208
|
var MindooDBTextBuffer = class {
|
|
992
1209
|
constructor(options) {
|
|
@@ -1040,7 +1257,7 @@ var MindooDBTextBuffer = class {
|
|
|
1040
1257
|
if (nextValue === this.valueInternal) {
|
|
1041
1258
|
return;
|
|
1042
1259
|
}
|
|
1043
|
-
const edit =
|
|
1260
|
+
const edit = computeSingleSplice2(this.valueInternal, nextValue);
|
|
1044
1261
|
this.splice(edit.index, edit.deleteCount, edit.insert ?? "");
|
|
1045
1262
|
}
|
|
1046
1263
|
/**
|
|
@@ -1107,7 +1324,7 @@ function readTextAtPath(data, path) {
|
|
|
1107
1324
|
}
|
|
1108
1325
|
return typeof value === "string" ? value : "";
|
|
1109
1326
|
}
|
|
1110
|
-
function
|
|
1327
|
+
function computeSingleSplice2(previous, next) {
|
|
1111
1328
|
let prefixLength = 0;
|
|
1112
1329
|
const maxPrefix = Math.min(previous.length, next.length);
|
|
1113
1330
|
while (prefixLength < maxPrefix && previous[prefixLength] === next[prefixLength]) {
|
|
@@ -1135,10 +1352,12 @@ import {
|
|
|
1135
1352
|
mindooDBViewLanguageHelpersByName
|
|
1136
1353
|
} from "mindoodb-view-language";
|
|
1137
1354
|
export {
|
|
1355
|
+
MindooDBRichTextHandle,
|
|
1138
1356
|
MindooDBTextBuffer,
|
|
1139
1357
|
abbreviateCanonicalName,
|
|
1140
1358
|
canPreviewAttachment,
|
|
1141
1359
|
createMindooDBAppBridge,
|
|
1360
|
+
createMindooDBRichTextHandle,
|
|
1142
1361
|
createMindooDBTextBuffer,
|
|
1143
1362
|
createViewLanguage,
|
|
1144
1363
|
expandAbbreviatedName
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { am as MindooDBAppLaunchContext, a2 as MindooDBAppDatabaseInfo, a3 as MindooDBAppDocumentApi, a1 as MindooDBAppCreateViewNavigatorInput, b3 as MindooDBAppViewNavigator, b5 as MindooDBAppViewNavigatorOpenOptions, f as MindooDBAppAttachmentApi, a as MindooDBAppBridge, aT as MindooDBAppSession, x as MindooDBAppBridgeRpcRequest, ad as MindooDBAppHostTheme, ba as MindooDBAppViewport, aZ as MindooDBAppUiPreferences, u as MindooDBAppBridgePortMessage } from '../types-CQt2ObMu.js';
|
|
2
2
|
import 'mindoodb-view-language';
|
|
3
3
|
|
|
4
4
|
type MaybePromise<T> = T | Promise<T>;
|