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/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 = computeSingleSplice(this.valueInternal, nextValue);
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 computeSingleSplice(previous, next) {
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
@@ -1,4 +1,4 @@
1
- import { ac as MindooDBAppLaunchContext, X as MindooDBAppDatabaseInfo, Y as MindooDBAppDocumentApi, W as MindooDBAppCreateViewNavigatorInput, aK as MindooDBAppViewNavigator, aM as MindooDBAppViewNavigatorOpenOptions, d as MindooDBAppAttachmentApi, a as MindooDBAppBridge, ay as MindooDBAppSession, q as MindooDBAppBridgeRpcRequest, a6 as MindooDBAppHostTheme, aR as MindooDBAppViewport, aE as MindooDBAppUiPreferences, n as MindooDBAppBridgePortMessage } from '../types-jzokkBX5.js';
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>;