import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
import {
  UndoOperation
} from "./chunk-J2PHTRHC.mjs";
import {
  __export
} from "./chunk-HSLMI22Q.mjs";

// src/plugin-operation/history/errors.ts
import { OperationError } from "@dxos/operation";
var EmptyHistoryError = class extends OperationError {
  constructor() {
    super("EMPTY_HISTORY", "Cannot undo: history is empty.");
  }
};

// src/plugin-operation/history/undo-mapping.ts
var undo_mapping_exports = {};
__export(undo_mapping_exports, {
  make: () => make,
  resolveMessage: () => resolveMessage
});
var make = (props) => props;
var resolveMessage = (message, input, output) => {
  if (message === void 0) {
    return void 0;
  }
  if (typeof message === "function") {
    return message(input, output);
  }
  return message;
};

// src/plugin-operation/history/undo-registry.ts
var undo_registry_exports = {};
__export(undo_registry_exports, {
  make: () => make2
});
var make2 = (getMappings) => {
  const lookup = (operation) => {
    const mappings = getMappings();
    const mapping = mappings.find((m) => m.operation.meta.key === operation.meta.key);
    if (!mapping) {
      return void 0;
    }
    return {
      inverse: mapping.inverse,
      deriveContext: mapping.deriveContext,
      message: mapping.message
    };
  };
  return {
    lookup
  };
};

// src/plugin-operation/history/history-tracker.ts
var history_tracker_exports = {};
__export(history_tracker_exports, {
  make: () => make3
});
import * as Effect from "effect/Effect";
import * as Stream from "effect/Stream";
import { runAndForwardErrors } from "@dxos/effect";
import { log } from "@dxos/log";
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-framework/src/plugin-operation/history/history-tracker.ts";
var HISTORY_LIMIT = 100;
var make3 = (invoker, undoRegistry) => {
  const history = [];
  const handleInvocation = (event) => {
    const mapping = undoRegistry.lookup(event.operation);
    if (!mapping) {
      return;
    }
    const inverseInput = mapping.deriveContext(event.input, event.output);
    if (inverseInput === void 0) {
      log("operation not undoable", {
        key: event.operation.meta.key
      }, {
        F: __dxlog_file,
        L: 58,
        S: void 0,
        C: (f, a) => f(...a)
      });
      return;
    }
    const entry = {
      operation: event.operation,
      input: event.input,
      output: event.output,
      inverse: mapping.inverse,
      inverseInput,
      timestamp: event.timestamp
    };
    history.push(entry);
    log("history entry added", {
      key: event.operation.meta.key,
      historyLength: history.length
    }, {
      F: __dxlog_file,
      L: 72,
      S: void 0,
      C: (f, a) => f(...a)
    });
    if (history.length > HISTORY_LIMIT) {
      history.splice(0, history.length - HISTORY_LIMIT);
    }
    const resolvedMessage = resolveMessage(mapping.message, event.input, event.output);
    Effect.runFork(invoker.invoke(UndoOperation.ShowUndo, {
      message: resolvedMessage
    }));
  };
  Effect.runFork(Stream.fromPubSub(invoker.invocations).pipe(Stream.runForEach((event) => Effect.sync(() => handleInvocation(event)))));
  const undo = () => {
    return Effect.gen(function* () {
      const entry = history.pop();
      if (!entry) {
        return yield* Effect.fail(new EmptyHistoryError());
      }
      log("undoing operation", {
        key: entry.operation.meta.key,
        inverseKey: entry.inverse.meta.key
      }, {
        F: __dxlog_file,
        L: 102,
        S: this,
        C: (f, a) => f(...a)
      });
      yield* invoker._invokeCore(entry.inverse, entry.inverseInput);
      log("undo completed", {
        key: entry.operation.meta.key
      }, {
        F: __dxlog_file,
        L: 107,
        S: this,
        C: (f, a) => f(...a)
      });
    });
  };
  const undoPromise = async () => {
    return runAndForwardErrors(undo()).then(() => ({})).catch((error) => {
      log.catch(error, void 0, {
        F: __dxlog_file,
        L: 115,
        S: void 0,
        C: (f, a) => f(...a)
      });
      return {
        error
      };
    });
  };
  const canUndo = () => {
    return history.length > 0;
  };
  return {
    undo,
    undoPromise,
    canUndo
  };
};

export {
  EmptyHistoryError,
  undo_mapping_exports,
  make2 as make,
  undo_registry_exports,
  make3 as make2,
  history_tracker_exports
};
//# sourceMappingURL=chunk-DHSHRYIB.mjs.map
