nano-git 0.3.1 → 0.3.2
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/workdir/change-index-plan.mjs +2 -2
- package/dist/workdir/change-index.mjs +5 -5
- package/dist/workdir/core.d.mts +12 -43
- package/dist/workdir/directory-view.mjs +2 -2
- package/dist/workdir/dirty-dir-plan.mjs +3 -3
- package/dist/workdir/file-backend.d.mts +34 -12
- package/dist/workdir/file-backend.mjs +67 -86
- package/dist/workdir/file.d.mts +2 -2
- package/dist/workdir/file.mjs +2 -2
- package/dist/workdir/ids.d.mts +1 -1
- package/dist/workdir/ids.mjs +3 -3
- package/dist/workdir/memory-backend.mjs +4 -39
- package/dist/workdir/memory.d.mts +2 -3
- package/dist/workdir/memory.mjs +2 -3
- package/dist/workdir/nodes.d.mts +7 -7
- package/dist/workdir/nodes.mjs +3 -3
- package/dist/workdir/overlay.d.mts +3 -3
- package/dist/workdir/sqlite-backend.d.mts +31 -14
- package/dist/workdir/sqlite-backend.mjs +113 -118
- package/dist/workdir/sqlite.d.mts +2 -2
- package/dist/workdir/sqlite.mjs +2 -2
- package/dist/workdir/state-store.d.mts +4 -4
- package/dist/workdir/{session-internal.mjs → workdir-path.mjs} +8 -8
- package/dist/workdir/{session-transaction.mjs → workdir-transaction.mjs} +9 -9
- package/dist/workdir/workdir.d.mts +30 -0
- package/dist/workdir/{session.mjs → workdir.mjs} +17 -17
- package/dist/workdir/write-tree.mjs +4 -4
- package/package.json +1 -1
- package/dist/workdir/memory-backend.d.mts +0 -17
- package/dist/workdir/session-id.mjs +0 -18
- package/dist/workdir/session.d.mts +0 -30
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { VirtualNotDirectoryError, VirtualNotFileError, VirtualPathAlreadyExistsError, VirtualPathNotFoundError } from "../core/errors.mjs";
|
|
2
2
|
import { VIRTUAL_ROOT_NODE_ID, originBackedNodeId } from "./ids.mjs";
|
|
3
|
-
import { mergeDirectoryChildren } from "./overlay.mjs";
|
|
4
3
|
import { readRepoTree, treeEntryToNodeOrigin } from "./origin.mjs";
|
|
4
|
+
import { mergeDirectoryChildren } from "./overlay.mjs";
|
|
5
5
|
import { assertValidVirtualPath, baseName, joinPath, parentPath, splitPathSegments } from "./path.mjs";
|
|
6
|
-
//#region src/workdir/
|
|
6
|
+
//#region src/workdir/workdir-path.ts
|
|
7
7
|
/**
|
|
8
|
-
* Virtual Workdir
|
|
8
|
+
* Virtual Workdir 路径解析与共享读视图
|
|
9
9
|
*
|
|
10
|
-
* 供
|
|
10
|
+
* 供 workdir.ts 与 write-tree.ts 复用:
|
|
11
11
|
* - 路径解析(resolvePath / resolveWriteTarget*)
|
|
12
12
|
* - 目录子项展开(listDirectoryChildren / getDirectoryChildrenView)
|
|
13
13
|
* - origin 节点懒注册(ensureNodeFromTreeEntry)
|
|
@@ -28,7 +28,7 @@ function joinChildPath(dirPath, name) {
|
|
|
28
28
|
}
|
|
29
29
|
function getRootNode(state) {
|
|
30
30
|
const root = state.getNode(VIRTUAL_ROOT_NODE_ID);
|
|
31
|
-
if (root === null) throw new Error("Virtual workdir
|
|
31
|
+
if (root === null) throw new Error("Virtual workdir is missing root node");
|
|
32
32
|
return root;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
@@ -265,7 +265,7 @@ function resolvePathByParentLookup(source, state, path) {
|
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
/**
|
|
268
|
-
* 确保 origin 条目对应的
|
|
268
|
+
* 确保 origin 条目对应的 workdir 节点已懒注册
|
|
269
269
|
*/
|
|
270
270
|
function ensureNodeFromTreeEntry(state, entry) {
|
|
271
271
|
const id = originBackedNodeId(entry.hash);
|
|
@@ -321,11 +321,11 @@ function buildAddedModes(state, dirNode) {
|
|
|
321
321
|
for (const name of dirNode.state.overlay.addedEntries.keys()) {
|
|
322
322
|
const nodeId = dirNode.state.overlay.addedEntries.get(name);
|
|
323
323
|
const node = state.getNode(nodeId);
|
|
324
|
-
if (node !== null) addedModes.set(name,
|
|
324
|
+
if (node !== null) addedModes.set(name, workdirNodeMode(node));
|
|
325
325
|
}
|
|
326
326
|
return addedModes;
|
|
327
327
|
}
|
|
328
|
-
function
|
|
328
|
+
function workdirNodeMode(node) {
|
|
329
329
|
if (node.state.kind === "directory") return "40000";
|
|
330
330
|
if (node.state.kind === "symlink") return "120000";
|
|
331
331
|
return node.state.mode;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createNodeId } from "./ids.mjs";
|
|
2
|
-
import { overlayBindEntry } from "./overlay.mjs";
|
|
3
|
-
import { cloneSessionNodeForCopy } from "./nodes.mjs";
|
|
4
2
|
import { readRepoBlobContent } from "./origin.mjs";
|
|
5
|
-
import {
|
|
3
|
+
import { overlayBindEntry } from "./overlay.mjs";
|
|
4
|
+
import { listDirectoryChildren } from "./workdir-path.mjs";
|
|
6
5
|
import { observeListedDirectoryChild } from "./directory-view.mjs";
|
|
7
|
-
|
|
6
|
+
import { cloneWorkdirNodeForCopy } from "./nodes.mjs";
|
|
7
|
+
//#region src/workdir/workdir-transaction.ts
|
|
8
8
|
/**
|
|
9
|
-
* Virtual Workdir
|
|
9
|
+
* Virtual Workdir 写事务与节点辅助函数
|
|
10
10
|
*
|
|
11
|
-
* 从
|
|
11
|
+
* 从 workdir.ts 提取,降低编排层复杂度:
|
|
12
12
|
* - 写操作事务生命周期管理
|
|
13
13
|
* - 父目录 overlay 更新
|
|
14
14
|
* - 节点状态统计(stat)
|
|
@@ -17,7 +17,7 @@ import { observeListedDirectoryChild } from "./directory-view.mjs";
|
|
|
17
17
|
/**
|
|
18
18
|
* 在 state store 事务边界内执行写操作。
|
|
19
19
|
*
|
|
20
|
-
* @param state -
|
|
20
|
+
* @param state - workdir 内部状态存储
|
|
21
21
|
* @param onBeforeCommit - 提交前回调(在事务 callback 内执行);可为 null
|
|
22
22
|
* @param onCommitted - 提交后回调(在事务 callback 外执行)
|
|
23
23
|
* @param fn - 实际写入逻辑
|
|
@@ -46,7 +46,7 @@ function updateParentOverlay(state, parentId, newOverlay) {
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
* 获取节点统计信息(用于
|
|
49
|
+
* 获取节点统计信息(用于 workdir.stat() 实现)
|
|
50
50
|
*/
|
|
51
51
|
function statNode(source, node, path) {
|
|
52
52
|
if (node.state.kind === "directory") return statDirectoryNode(node);
|
|
@@ -91,7 +91,7 @@ function statDirectoryNode(node) {
|
|
|
91
91
|
*/
|
|
92
92
|
function cloneNodeGraphForCopy(source, state, node, path) {
|
|
93
93
|
const newNodeId = createNodeId();
|
|
94
|
-
const cloned =
|
|
94
|
+
const cloned = cloneWorkdirNodeForCopy(node, newNodeId);
|
|
95
95
|
state.setNode(cloned);
|
|
96
96
|
if (node.state.kind !== "directory" || cloned.state.kind !== "directory") return newNodeId;
|
|
97
97
|
let overlay = cloned.state.overlay;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ObjectDatabase } from "../core/types/odb.mjs";
|
|
2
|
+
import { CreateVirtualWorkdirOptions, VirtualWorkdir } from "./core.mjs";
|
|
3
|
+
import { VirtualWorkdirStateStore } from "./state-store.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/workdir/workdir.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* 基于 ObjectDatabase 创建 VirtualWorkdir
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const repo = createMemoryRepository();
|
|
12
|
+
* const tree = repo.createTree([]);
|
|
13
|
+
* const workdir = createVirtualWorkdir(repo.objects, { baseTree: tree });
|
|
14
|
+
* expect(workdir.readdir()).toEqual([]);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare function createVirtualWorkdir(source: ObjectDatabase, options: CreateVirtualWorkdirOptions): VirtualWorkdir;
|
|
18
|
+
/**
|
|
19
|
+
* 基于已有状态存储打开 VirtualWorkdir
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const store = createVirtualWorkdirMemoryStateStore(tree);
|
|
24
|
+
* const workdir = openVirtualWorkdir(repo.objects, store);
|
|
25
|
+
* expect(workdir.baseTree).toBe(tree);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function openVirtualWorkdir(source: ObjectDatabase, state: VirtualWorkdirStateStore): VirtualWorkdir;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { createVirtualWorkdir, openVirtualWorkdir };
|
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
import { VirtualNotDirectoryError, VirtualNotFileError, VirtualNotSymlinkError, VirtualPathAlreadyExistsError, VirtualPathNotFoundError, VirtualRevertNotSupportedError } from "../core/errors.mjs";
|
|
2
2
|
import { createNodeId } from "./ids.mjs";
|
|
3
|
-
import { overlayBindEntry, overlayRenameEntry, overlayTombstoneEntry } from "./overlay.mjs";
|
|
4
|
-
import { revertNodeState } from "./nodes.mjs";
|
|
5
3
|
import { modeToVirtualEntryKind, readRepoBlobContent } from "./origin.mjs";
|
|
4
|
+
import { overlayBindEntry, overlayRenameEntry, overlayTombstoneEntry } from "./overlay.mjs";
|
|
6
5
|
import { assertValidVirtualPath, normalizeDirectoryPath } from "./path.mjs";
|
|
7
|
-
import { getDirectoryChildrenView, getRootNode, requireExistingWriteTarget, requireMissingWriteTarget, resolveLeafWriteTarget, resolvePath, resolveWriteTransfer } from "./
|
|
6
|
+
import { getDirectoryChildrenView, getRootNode, requireExistingWriteTarget, requireMissingWriteTarget, resolveLeafWriteTarget, resolvePath, resolveWriteTransfer } from "./workdir-path.mjs";
|
|
8
7
|
import { createChangeIndexPlanner } from "./change-index-plan.mjs";
|
|
9
8
|
import { computeVirtualDiff, rebuildNormalizedChangeIndex, refreshChangeRecordForPath, replaceChangeRecords, rewriteChangeRecordForRename, writeChangeRecordForCopy } from "./change-index.mjs";
|
|
10
9
|
import { createDirtyDirPlanner } from "./dirty-dir-plan.mjs";
|
|
11
|
-
import {
|
|
12
|
-
import { writeTreeFromSession } from "./write-tree.mjs";
|
|
10
|
+
import { revertNodeState } from "./nodes.mjs";
|
|
13
11
|
import { createVirtualWorkdirMemoryStateStore } from "./memory-backend.mjs";
|
|
14
|
-
|
|
12
|
+
import { cloneNodeGraphForCopy, runInWriteTransaction, statDirectoryNode, statNode, updateParentOverlay } from "./workdir-transaction.mjs";
|
|
13
|
+
import { writeTreeFromSession } from "./write-tree.mjs";
|
|
14
|
+
//#region src/workdir/workdir.ts
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* VirtualWorkdir 行为编排
|
|
17
17
|
*
|
|
18
18
|
* Phase 5:完整文件/目录 rename 与 copy 语义。
|
|
19
19
|
*/
|
|
20
20
|
/**
|
|
21
|
-
* 基于 ObjectDatabase 创建
|
|
21
|
+
* 基于 ObjectDatabase 创建 VirtualWorkdir
|
|
22
22
|
*
|
|
23
23
|
* @example
|
|
24
24
|
* ```ts
|
|
25
25
|
* const repo = createMemoryRepository();
|
|
26
26
|
* const tree = repo.createTree([]);
|
|
27
|
-
* const
|
|
28
|
-
* expect(
|
|
27
|
+
* const workdir = createVirtualWorkdir(repo.objects, { baseTree: tree });
|
|
28
|
+
* expect(workdir.readdir()).toEqual([]);
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
|
-
function
|
|
32
|
-
return
|
|
31
|
+
function createVirtualWorkdir(source, options) {
|
|
32
|
+
return openVirtualWorkdir(source, createVirtualWorkdirMemoryStateStore(options.baseTree));
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* 基于已有状态存储打开
|
|
35
|
+
* 基于已有状态存储打开 VirtualWorkdir
|
|
36
36
|
*
|
|
37
37
|
* @example
|
|
38
38
|
* ```ts
|
|
39
39
|
* const store = createVirtualWorkdirMemoryStateStore(tree);
|
|
40
|
-
* const
|
|
41
|
-
* expect(
|
|
40
|
+
* const workdir = openVirtualWorkdir(repo.objects, store);
|
|
41
|
+
* expect(workdir.baseTree).toBe(tree);
|
|
42
42
|
* ```
|
|
43
43
|
*/
|
|
44
|
-
function
|
|
44
|
+
function openVirtualWorkdir(source, state) {
|
|
45
45
|
const currentNodeHashes = /* @__PURE__ */ new Map();
|
|
46
46
|
const invalidateDiffCaches = () => {
|
|
47
47
|
currentNodeHashes.clear();
|
|
@@ -277,4 +277,4 @@ function openVirtualWorkdirSession(source, state) {
|
|
|
277
277
|
};
|
|
278
278
|
}
|
|
279
279
|
//#endregion
|
|
280
|
-
export {
|
|
280
|
+
export { createVirtualWorkdir, openVirtualWorkdir };
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { writeObject } from "../objects/raw.mjs";
|
|
2
2
|
import { readRepoTree } from "./origin.mjs";
|
|
3
|
-
import { listDirectoryChildren } from "./
|
|
3
|
+
import { listDirectoryChildren } from "./workdir-path.mjs";
|
|
4
4
|
import { createNamedOriginChildLookup, observeListedDirectoryChild, observeNamedDirectoryChild, planAffectedDirectoryChildren } from "./directory-view.mjs";
|
|
5
5
|
import { materializeDirtyDirSummary } from "./dirty-dir.mjs";
|
|
6
6
|
//#region src/workdir/write-tree.ts
|
|
7
7
|
/**
|
|
8
8
|
* Virtual Workdir overlay -> tree 最小化编译
|
|
9
9
|
*
|
|
10
|
-
* 遍历
|
|
10
|
+
* 遍历 workdir 的目录 overlay,将受影响的目录重写为新 tree,
|
|
11
11
|
* 未修改的 repo-backed 子树/文件尽量复用原对象哈希。
|
|
12
12
|
*
|
|
13
13
|
* writeTree() 成功后不清空 overlay,不推进 baseTree。
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
16
|
-
* 将当前
|
|
16
|
+
* 将当前 workdir 状态编译为新的根 tree
|
|
17
17
|
*
|
|
18
18
|
* 只重写受 overlay 影响的目录;文件/符号链接仅在 materialized 时写新 blob。
|
|
19
19
|
* 未修改的 repo-backed 条目直接复用 origin hash。
|
|
20
20
|
*
|
|
21
21
|
* @param source - 可写对象数据库(用于写入新 blob/tree)
|
|
22
|
-
* @param state -
|
|
22
|
+
* @param state - workdir 内部状态
|
|
23
23
|
* @returns 新根 tree 的 SHA-1
|
|
24
24
|
*
|
|
25
25
|
* @example
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { VirtualWorkdirBackend } from "./core.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/workdir/memory-backend.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* 创建内存版 Virtual Workdir backend
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const backend = createMemoryVirtualWorkdirBackend();
|
|
10
|
-
* const sessionId = backend.createSession({ baseTree: tree });
|
|
11
|
-
* const session = backend.openSession(repo.objects, sessionId);
|
|
12
|
-
* expect(session.baseTree).toBe(tree);
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
declare function createMemoryVirtualWorkdirBackend(): VirtualWorkdirBackend;
|
|
16
|
-
//#endregion
|
|
17
|
-
export { createMemoryVirtualWorkdirBackend };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
//#region src/workdir/session-id.ts
|
|
2
|
-
let nextSessionCounter = 1;
|
|
3
|
-
/**
|
|
4
|
-
* 分配新的 session ID
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const sessionId = createVirtualWorkdirSessionId();
|
|
9
|
-
* expect(String(sessionId).startsWith("session:")).toBe(true);
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
|
-
function createVirtualWorkdirSessionId() {
|
|
13
|
-
const id = `session:${nextSessionCounter}`;
|
|
14
|
-
nextSessionCounter += 1;
|
|
15
|
-
return id;
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
export { createVirtualWorkdirSessionId };
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { ObjectDatabase } from "../core/types/odb.mjs";
|
|
2
|
-
import { CreateVirtualWorkdirSessionOptions, VirtualWorkdirSession } from "./core.mjs";
|
|
3
|
-
import { VirtualWorkdirStateStore } from "./state-store.mjs";
|
|
4
|
-
|
|
5
|
-
//#region src/workdir/session.d.ts
|
|
6
|
-
/**
|
|
7
|
-
* 基于 ObjectDatabase 创建 VirtualWorkdirSession
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* const repo = createMemoryRepository();
|
|
12
|
-
* const tree = repo.createTree([]);
|
|
13
|
-
* const session = createVirtualWorkdirSession(repo.objects, { baseTree: tree });
|
|
14
|
-
* expect(session.readdir()).toEqual([]);
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
declare function createVirtualWorkdirSession(source: ObjectDatabase, options: CreateVirtualWorkdirSessionOptions): VirtualWorkdirSession;
|
|
18
|
-
/**
|
|
19
|
-
* 基于已有状态存储打开 session
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* const store = createVirtualWorkdirMemoryStateStore(tree);
|
|
24
|
-
* const session = openVirtualWorkdirSession(repo.objects, store);
|
|
25
|
-
* expect(session.baseTree).toBe(tree);
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
declare function openVirtualWorkdirSession(source: ObjectDatabase, state: VirtualWorkdirStateStore): VirtualWorkdirSession;
|
|
29
|
-
//#endregion
|
|
30
|
-
export { createVirtualWorkdirSession, openVirtualWorkdirSession };
|