New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@automerge/automerge-codemirror

Package Overview
Dependencies
Maintainers
4
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@automerge/automerge-codemirror - npm Package Compare versions

Comparing version 0.0.10 to 0.0.11

CHANGELOG.md

3

dist/amToCodemirror.d.ts
import { Patch, Prop } from "@automerge/automerge";
import { EditorSelection } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
export default function (view: EditorView, selection: EditorSelection, target: Prop[], patches: Patch[]): void;
export declare const applyAmPatchesToCm: (view: EditorView, target: Prop[], patches: Patch[]) => void;

@@ -1,4 +0,5 @@

import { ChangeSet, } from "@codemirror/state";
import { ChangeSet } from "@codemirror/state";
import { reconcileAnnotationType } from "./plugin";
export default function (view, selection, target, patches) {
export const applyAmPatchesToCm = (view, target, patches) => {
let selection = view.state.selection;
for (const patch of patches) {

@@ -19,3 +20,3 @@ const changeSpec = handlePatch(patch, target, view.state);

});
}
};
function handlePatch(patch, target, state) {

@@ -22,0 +23,0 @@ if (patch.action === "insert") {

@@ -1,7 +0,5 @@

import { next as am } from "@automerge/automerge";
import { next as A } from "@automerge/automerge";
import { DocHandle } from "@automerge/automerge-repo";
import { Heads } from "@automerge/automerge";
import { EditorState, Transaction } from "@codemirror/state";
import { type Field } from "./plugin";
type Update = (atHeads: Heads, change: (doc: am.Doc<unknown>) => void) => Heads | undefined;
export default function (field: Field, update: Update, transactions: Transaction[], state: EditorState): Heads | undefined;
export {};
import { Transaction } from "@codemirror/state";
export declare const applyCmTransactionsToAmHandle: (handle: DocHandle<unknown>, path: A.Prop[], transactions: Transaction[]) => A.Heads | undefined;

@@ -1,26 +0,19 @@

import { next as am } from "@automerge/automerge";
export default function (field, update, transactions, state) {
const { lastHeads, path } = state.field(field);
// We don't want to call `automerge.updateAt` if there are no changes.
// Otherwise later on `automerge.diff` will return empty patches that result in a no-op but still mess up the selection.
let hasChanges = false;
for (const tr of transactions) {
if (!tr.changes.empty) {
tr.changes.iterChanges(() => {
hasChanges = true;
});
}
import { next as A } from "@automerge/automerge";
import { isReconcileTx } from "./plugin";
export const applyCmTransactionsToAmHandle = (handle, path, transactions) => {
const transactionsWithChanges = transactions.filter(tr => !isReconcileTx(tr) && !tr.changes.empty);
if (transactionsWithChanges.length === 0) {
return;
}
if (!hasChanges) {
return undefined;
}
const newHeads = update(lastHeads, (doc) => {
for (const tr of transactions) {
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
am.splice(doc, path, fromA, toA - fromA, inserted.toString());
handle.change((doc) => {
transactionsWithChanges.forEach(tr => {
tr.changes.iterChanges((fromA, toA, fromB, _toB, inserted) => {
// We are cloning the path as `am.splice` calls `.unshift` on it, modifying it in place,
// causing the path to be broken on subsequent changes
A.splice(doc, path.slice(), fromB, toA - fromA, inserted.toString());
});
}
});
});
return newHeads;
}
return A.getHeads(handle.docSync());
};
//# sourceMappingURL=codeMirrorToAm.js.map

@@ -1,2 +0,1 @@

export { plugin } from "./plugin";
export { PatchSemaphore } from "./PatchSemaphore";
export { automergeSyncPlugin } from "./plugin";

@@ -1,3 +0,2 @@

export { plugin } from "./plugin";
export { PatchSemaphore } from "./PatchSemaphore";
export { automergeSyncPlugin } from "./plugin";
//# sourceMappingURL=index.js.map

@@ -1,20 +0,19 @@

import { EditorState, StateEffect, StateField, Transaction, TransactionSpec } from "@codemirror/state";
import { Doc, Heads, Prop } from "@automerge/automerge";
export type Value = {
lastHeads: Heads;
path: Prop[];
unreconciledTransactions: Transaction[];
import { next as A } from "@automerge/automerge";
import { EditorView, ViewPlugin, ViewUpdate } from "@codemirror/view";
import { Transaction } from "@codemirror/state";
import { DocHandle } from "@automerge/automerge-repo";
export declare const reconcileAnnotationType: import("@codemirror/state").AnnotationType<unknown>;
export declare const isReconcileTx: (tr: Transaction) => boolean;
type AutomergeSyncPluginConfig = {
handle: DocHandle<any>;
path: A.Prop[];
};
type UpdateHeads = {
newHeads: Heads;
};
export declare const effectType: import("@codemirror/state").StateEffectType<UpdateHeads>;
export declare function updateHeads(newHeads: Heads): StateEffect<UpdateHeads>;
export declare function getLastHeads(state: EditorState, field: Field): Heads;
export declare function getPath(state: EditorState, field: Field): Prop[];
export type Field = StateField<Value>;
export declare function plugin<T>(doc: Doc<T>, path: Prop[]): StateField<Value>;
export declare const reconcileAnnotationType: import("@codemirror/state").AnnotationType<unknown>;
export declare function isReconcileTx(tr: Transaction): boolean;
export declare function makeReconcile(tr: TransactionSpec): void;
export declare const automergeSyncPlugin: ({ handle, path, }: AutomergeSyncPluginConfig) => ViewPlugin<{
view: EditorView;
reconciledHeads: A.Heads;
isProcessingCmTransaction: boolean;
update(update: ViewUpdate): void;
onChange: () => void;
destroy(): void;
}>;
export {};

@@ -1,68 +0,52 @@

import { Annotation, StateEffect, StateField, } from "@codemirror/state";
import * as automerge from "@automerge/automerge";
export const effectType = StateEffect.define({});
export function updateHeads(newHeads) {
return effectType.of({ newHeads });
}
export function getLastHeads(state, field) {
return state.field(field).lastHeads;
}
export function getPath(state, field) {
return state.field(field).path;
}
export function plugin(doc, path) {
return StateField.define({
create() {
return {
lastHeads: automerge.getHeads(doc),
unreconciledTransactions: [],
path: path.slice(),
};
},
update(value, tr) {
const result = {
lastHeads: value.lastHeads,
unreconciledTransactions: value.unreconciledTransactions.slice(),
path: path.slice(),
};
let clearUnreconciled = false;
for (const effect of tr.effects) {
if (effect.is(effectType)) {
result.lastHeads = effect.value.newHeads;
clearUnreconciled = true;
}
import { next as A } from "@automerge/automerge";
import { ViewPlugin } from "@codemirror/view";
import { Annotation } from "@codemirror/state";
import { applyCmTransactionsToAmHandle } from "./codeMirrorToAm";
import { applyAmPatchesToCm } from "./amToCodemirror";
export const reconcileAnnotationType = Annotation.define();
export const isReconcileTx = (tr) => !!tr.annotation(reconcileAnnotationType);
export const automergeSyncPlugin = ({ handle, path, }) => {
if (!handle.isReady) {
throw new Error("ensure the handle is ready before initializing the automergeSyncPlugin");
}
return ViewPlugin.fromClass(class {
view;
reconciledHeads = A.getHeads(handle.docSync());
isProcessingCmTransaction = false;
constructor(view) {
this.view = view;
this.onChange = this.onChange.bind(this);
handle.on("change", this.onChange);
}
update(update) {
// start processing codemirror transaction
// changes that are created through the transaction are ignored in the change listener on the handle
this.isProcessingCmTransaction = true;
const newHeads = applyCmTransactionsToAmHandle(handle, path, update.transactions);
if (newHeads) {
this.reconciledHeads = newHeads;
}
if (clearUnreconciled) {
result.unreconciledTransactions = [];
// finish processing transaction
this.isProcessingCmTransaction = false;
}
onChange = () => {
// ignore changes that where triggered while processing a codemirror transaction
if (this.isProcessingCmTransaction) {
return;
}
else {
if (!isReconcileTx(tr)) {
result.unreconciledTransactions.push(tr);
}
const currentHeads = A.getHeads(handle.docSync());
if (A.equals(currentHeads, this.reconciledHeads)) {
return;
}
return result;
},
// get the diff between the reconciled heads and the new heads
// and apply that to the codemirror doc
const patches = A.diff(handle.docSync(), this.reconciledHeads, currentHeads);
applyAmPatchesToCm(this.view, path, patches);
this.reconciledHeads = currentHeads;
};
destroy() {
handle.off("change", this.onChange);
}
});
}
export const reconcileAnnotationType = Annotation.define();
export function isReconcileTx(tr) {
return !!tr.annotation(reconcileAnnotationType);
}
export function makeReconcile(tr) {
if (tr.annotations != null) {
if (tr.annotations instanceof Array) {
tr.annotations = [...tr.annotations, reconcileAnnotationType.of({})];
}
else {
tr.annotations = [tr.annotations, reconcileAnnotationType.of({})];
}
}
else {
tr.annotations = [reconcileAnnotationType.of({})];
}
//return {
//...tr,
//annotations: reconcileAnnotationType.of({})
//}
}
};
//# sourceMappingURL=plugin.js.map
{
"name": "@automerge/automerge-codemirror",
"version": "0.0.10",
"version": "0.0.11",
"main": "dist/index.js",

@@ -8,2 +8,3 @@ "license": "MIT",

"build": "yarn tsc -p tsconfig.build.json",
"watch": "yarn tsc-watch -p tsconfig.build.json",
"lint": "eslint .",

@@ -18,3 +19,3 @@ "prettier": "prettier '**/*.{ts,tsx,}' --check",

"dependencies": {
"@automerge/automerge": "^2.1.7",
"@automerge/automerge": "^2.1.9",
"@codemirror/state": "^6.3.0",

@@ -27,2 +28,3 @@ "@codemirror/view": "^6.21.3",

"@cypress/react18": "^2.0.0",
"@types/react": "^18.2.79",
"@typescript-eslint/eslint-plugin": "^5.60.0",

@@ -37,2 +39,3 @@ "@typescript-eslint/parser": "^5.60.0",

"react-dom": "^18.2.0",
"tsc-watch": "^6.2.0",
"typescript": "^5.1.3",

@@ -39,0 +42,0 @@ "vite": "^4.3.9",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc