UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

251 lines (248 loc) 7.86 kB
import { useSetAtom } from "../../chunks/chunk-WF77DMLN.js"; import { atomFamily } from "../../chunks/chunk-ZHH24SIG.js"; import { atom } from "../../chunks/chunk-OBOPLPUQ.js"; import { pLimit } from "../../chunks/chunk-QQTYTFWR.js"; import { __commonJS, __toESM } from "../../chunks/chunk-U5RRZUYZ.js"; // node_modules/debounce-promise/dist/index.js var require_dist = __commonJS({ "node_modules/debounce-promise/dist/index.js"(exports, module) { "use strict"; module.exports = function debounce2(fn) { var wait = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0; var options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; var lastCallAt = void 0; var deferred = void 0; var timer = void 0; var pendingArgs = []; return function debounced() { var currentWait = getWait(wait); var currentTime = (/* @__PURE__ */ new Date()).getTime(); var isCold = !lastCallAt || currentTime - lastCallAt > currentWait; lastCallAt = currentTime; for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (isCold && options.leading) { return options.accumulate ? Promise.resolve(fn.call(this, [args])).then(function(result) { return result[0]; }) : Promise.resolve(fn.call.apply(fn, [this].concat(args))); } if (deferred) { clearTimeout(timer); } else { deferred = defer(); } pendingArgs.push(args); timer = setTimeout(flush.bind(this), currentWait); if (options.accumulate) { var argsIndex = pendingArgs.length - 1; return deferred.promise.then(function(results) { return results[argsIndex]; }); } return deferred.promise; }; function flush() { var thisDeferred = deferred; clearTimeout(timer); Promise.resolve(options.accumulate ? fn.call(this, pendingArgs) : fn.apply(this, pendingArgs[pendingArgs.length - 1])).then(thisDeferred.resolve, thisDeferred.reject); pendingArgs = []; deferred = null; } }; function getWait(wait) { return typeof wait === "function" ? wait() : wait; } function defer() { var deferred = {}; deferred.promise = new Promise(function(resolve, reject) { deferred.resolve = resolve; deferred.reject = reject; }); return deferred; } } }); // src/dashboard/atoms/DbAtoms.ts var import_debounce_promise = __toESM(require_dist(), 1); import { Database } from "alinea/backend"; import { EntryResolver } from "alinea/backend/resolver/EntryResolver"; import { Entry } from "alinea/core"; import { applySuffix, entryFileName, pathSuffix } from "alinea/core/EntryFilenames"; import { Graph } from "alinea/core/Graph"; import { MutationType } from "alinea/core/Mutation"; import { createEntryRow, entryParentPaths, publishEntryRow } from "alinea/core/util/EntryRows"; import { useEffect } from "react"; import { createPersistentStore } from "../util/PersistentStore.js"; import { clientAtom, configAtom } from "./DashboardAtoms.js"; var persistentStoreAtom = atom(createPersistentStore); var limit = pLimit(1); var dbHashAtom = atom(async (get) => { const db = await get(localDbAtom); get(changedEntriesAtom); const meta = await db.db.meta(); return meta.contentHash; }); var localDbAtom = atom(async (get, set) => { const config = get(configAtom); const client = get(clientAtom); const { store, clear, flush } = await get(persistentStoreAtom); let db = new Database(config, store); try { await db.init(); } catch { await clear(); db = new Database(config, store); } const resolver = new EntryResolver(db, config.schema); const syncDb = async (force = false) => { const changed = await db.syncWith(client, force); if (changed.length > 0) await flush(); return changed; }; const debounceSync = (0, import_debounce_promise.default)(syncDb, 100); const sync = (force) => limit(() => debounceSync(force).catch(() => [])); const applyMutations = async (mutations, commitHash) => { return limit(async () => { const update = await db.applyMutations(mutations, commitHash); await flush(); return update; }); }; await limit(syncDb); return { db, applyMutations, resolve: resolver.resolve, sync }; }); async function suffixPaths(config, graph, mutations) { const res = []; for (const mutation of mutations) { switch (mutation.type) { case MutationType.Create: { const { entry } = mutation; const sameLocation = Entry.root.is(entry.root).and( Entry.workspace.is(entry.workspace), Entry.locale.is(entry.locale) ); const sameParent = Entry.parent.is(entry.parent ?? null); const isExact = Entry.path.is(entry.path); const startsWith = Entry.path.like(entry.path + "-%"); const condition = sameLocation.and(sameParent, isExact.or(startsWith)); const conflictingPaths = await graph.preferPublished.find( Entry().where(condition).select(Entry.path) ); const suffix = pathSuffix(entry.path, conflictingPaths); if (suffix) { const updated = { ...entry, data: { ...entry.data, path: applySuffix(entry.path, suffix) } }; const suffixedEntry = await createEntryRow( config, publishEntryRow(config, updated) ); const parentPaths = entryParentPaths(config, entry); res.push({ ...mutation, file: entryFileName( config, publishEntryRow(config, updated), parentPaths ), entry: suffixedEntry }); continue; } } default: res.push(mutation); } } return res; } var mutateAtom = atom( null, async (get, set, ...mutations) => { const client = get(clientAtom); const config = get(configAtom); const graph = await get(graphAtom); const normalized = await limit(() => suffixPaths(config, graph, mutations)); const { commitHash } = await client.mutate(normalized); const { applyMutations } = await get(localDbAtom); if (normalized.length === 0) return; const changed = await applyMutations(normalized, commitHash); set(changedEntriesAtom, changed); } ); var dbUpdateAtom = atom( null, async (get, set, force = false) => { const { sync } = await get(localDbAtom); const changed = await sync(force); set(changedEntriesAtom, changed); } ); var graphAtom = atom(async (get) => { const config = get(configAtom); const { resolve } = await get(localDbAtom); return new Graph(config, resolve); }); var changedAtom = atom([]); var changedEntriesAtom = atom( (get) => get(changedAtom), (get, set, i18nIds) => { set(changedAtom, i18nIds); for (const i18nId of i18nIds) set(entryRevisionAtoms(i18nId)); } ); var entryRevisionAtoms = atomFamily((i18nId) => { const revision = atom(0); return atom( (get) => get(revision), (get, set) => set(revision, (i) => i + 1) ); }); function useMutate() { return useSetAtom(mutateAtom); } function useDbUpdater(everySeconds = 30) { const forceDbUpdate = useSetAtom(dbUpdateAtom); useEffect(() => { let interval = 0; interval = setInterval(forceDbUpdate, everySeconds * 1e3); return () => { clearInterval(interval); }; }, [everySeconds, forceDbUpdate]); } export { changedEntriesAtom, dbHashAtom, dbUpdateAtom, entryRevisionAtoms, graphAtom, mutateAtom, persistentStoreAtom, useDbUpdater, useMutate };