gitsheets 0.22.4 → 1.0.3

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.
Files changed (72) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +21 -0
  3. package/bin/gitsheets +5 -0
  4. package/dist/cli/index.d.ts +2 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +256 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/errors.d.ts +72 -0
  9. package/dist/errors.d.ts.map +1 -0
  10. package/dist/errors.js +74 -0
  11. package/dist/errors.js.map +1 -0
  12. package/dist/index.d.ts +17 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +12 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/patch.d.ts +2 -0
  17. package/dist/patch.d.ts.map +1 -0
  18. package/dist/patch.js +39 -0
  19. package/dist/patch.js.map +1 -0
  20. package/dist/path-template/index.d.ts +42 -0
  21. package/dist/path-template/index.d.ts.map +1 -0
  22. package/dist/path-template/index.js +288 -0
  23. package/dist/path-template/index.js.map +1 -0
  24. package/dist/push-daemon.d.ts +53 -0
  25. package/dist/push-daemon.d.ts.map +1 -0
  26. package/dist/push-daemon.js +148 -0
  27. package/dist/push-daemon.js.map +1 -0
  28. package/dist/repository.d.ts +67 -0
  29. package/dist/repository.d.ts.map +1 -0
  30. package/dist/repository.js +322 -0
  31. package/dist/repository.js.map +1 -0
  32. package/dist/sheet.d.ts +107 -0
  33. package/dist/sheet.d.ts.map +1 -0
  34. package/dist/sheet.js +605 -0
  35. package/dist/sheet.js.map +1 -0
  36. package/dist/store.d.ts +41 -0
  37. package/dist/store.d.ts.map +1 -0
  38. package/dist/store.js +49 -0
  39. package/dist/store.js.map +1 -0
  40. package/dist/toml.d.ts +11 -0
  41. package/dist/toml.d.ts.map +1 -0
  42. package/dist/toml.js +28 -0
  43. package/dist/toml.js.map +1 -0
  44. package/dist/transaction.d.ts +96 -0
  45. package/dist/transaction.d.ts.map +1 -0
  46. package/dist/transaction.js +227 -0
  47. package/dist/transaction.js.map +1 -0
  48. package/dist/validation.d.ts +37 -0
  49. package/dist/validation.d.ts.map +1 -0
  50. package/dist/validation.js +105 -0
  51. package/dist/validation.js.map +1 -0
  52. package/package.json +41 -35
  53. package/bin/cli.js +0 -61
  54. package/commands/edit.js +0 -90
  55. package/commands/normalize.js +0 -81
  56. package/commands/query.js +0 -206
  57. package/commands/read.js +0 -64
  58. package/commands/singer-target.js +0 -214
  59. package/commands/upsert.js +0 -260
  60. package/lib/GitSheets.js +0 -464
  61. package/lib/Repository.js +0 -88
  62. package/lib/Sheet.js +0 -625
  63. package/lib/errors.js +0 -21
  64. package/lib/hologit.js +0 -1
  65. package/lib/logger.js +0 -18
  66. package/lib/path/BaseComponent.js +0 -24
  67. package/lib/path/ExpressionComponent.js +0 -26
  68. package/lib/path/FieldComponent.js +0 -13
  69. package/lib/path/LiteralComponent.js +0 -12
  70. package/lib/path/Query.js +0 -18
  71. package/lib/path/Template.js +0 -214
  72. package/server.js +0 -120
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-daemon.js","sourceRoot":"","sources":["../src/push-daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { Repo as HologitRepo } from 'hologit';
2
+ import type { RecordLike } from './path-template/index.js';
3
+ import { PushDaemon, type PushDaemonOptions } from './push-daemon.js';
4
+ import { Sheet } from './sheet.js';
5
+ import { type TransactionHandler, type TransactionOptions, type TransactionResult } from './transaction.js';
6
+ import type { StandardSchemaV1 } from './validation.js';
7
+ export interface OpenRepoOptions {
8
+ /** Path to a `.git` directory. If omitted, discovered from the cwd upward. */
9
+ readonly gitDir?: string;
10
+ /** Working tree path; default `null` (bare-style operation). */
11
+ readonly workTree?: string | null;
12
+ }
13
+ export interface OpenSheetOptions<T extends RecordLike = RecordLike> {
14
+ /** Sub-directory under the data tree to scope this sheet to; default '.'. */
15
+ readonly root?: string;
16
+ /** Standard Schema validator; runs after the persisted JSON Schema. */
17
+ readonly validator?: StandardSchemaV1<unknown, T>;
18
+ }
19
+ /** Options for {@link Repository.openSheets}. No `validator` — use {@link openStore} for that. */
20
+ export interface OpenSheetsOptions {
21
+ /** Sub-directory under the data tree to scope every sheet to; default '.'. */
22
+ readonly root?: string;
23
+ }
24
+ export declare class Repository {
25
+ #private;
26
+ constructor(hologitRepo: HologitRepo);
27
+ /** Discover a `.git` upward from `cwd` and open it. */
28
+ static fromCwd(): Promise<Repository>;
29
+ /** Open a specific git directory. */
30
+ static open(opts: OpenRepoOptions): Promise<Repository>;
31
+ /**
32
+ * @internal — Direct access to the underlying hologit substrate is reserved
33
+ * for the library. Consumers should use the public Repository surface; the
34
+ * substrate is an implementation detail and will swap to Rust holo-tree in
35
+ * v1.1 with no public-API change ([#127]).
36
+ */
37
+ get hologitRepo(): HologitRepo;
38
+ get gitDir(): string;
39
+ /** @internal — used by Sheet to enforce strict mode. Library cross-class signal, not a consumer API. */
40
+ isStrictMode(): boolean;
41
+ /** Switch to strict mode — mutations outside repo.transact throw. One-way. */
42
+ requireExplicitTransactions(): void;
43
+ /** Resolve a ref or commit hash. Returns the full commit hash or null. */
44
+ resolveRef(ref: string): Promise<string | null>;
45
+ /**
46
+ * Open a Sheet handle bound to the workspace at the resolved ref (default
47
+ * HEAD). Throws ConfigError(config_missing) when `.gitsheets/<name>.toml`
48
+ * is absent.
49
+ */
50
+ openSheet<T extends RecordLike = RecordLike>(name: string, opts?: OpenSheetOptions<T>): Promise<Sheet<T>>;
51
+ /** Discover every sheet declared in `<root>/.gitsheets/*.toml`. */
52
+ openSheets(opts?: OpenSheetsOptions): Promise<Record<string, Sheet>>;
53
+ /**
54
+ * Run a handler inside a transaction. On handler success, commit; on throw,
55
+ * discard the tree. See specs/api/transaction.md.
56
+ */
57
+ transact<T>(opts: TransactionOptions, handler: TransactionHandler<T>): Promise<TransactionResult<T>>;
58
+ /**
59
+ * Start an async push daemon for this repo. Only one daemon may be active
60
+ * at a time; throws TransactionError(push_daemon_running) on contention.
61
+ * See specs/behaviors/push-sync.md.
62
+ */
63
+ startPushDaemon(opts: PushDaemonOptions): Promise<PushDaemon>;
64
+ }
65
+ /** Convenience factory: `openRepo({ gitDir? })`. */
66
+ export declare function openRepo(opts?: OpenRepoOptions): Promise<Repository>;
67
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,SAAS,CAAC;AAI9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EACL,UAAU,EAEV,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IACjE,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;CACnD;AAED,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,UAAU;;gBAOT,WAAW,EAAE,WAAW;IAIpC,uDAAuD;WAC1C,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAK3C,qCAAqC;WACxB,IAAI,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAY7D;;;;;OAKG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,wGAAwG;IACxG,YAAY,IAAI,OAAO;IAIvB,8EAA8E;IAC9E,2BAA2B,IAAI,IAAI;IAInC,0EAA0E;IACpE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIrD;;;;OAIG;IACG,SAAS,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EAC/C,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,gBAAgB,CAAC,CAAC,CAAM,GAC7B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAqBpB,mEAAmE;IAC7D,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IA4B9E;;;OAGG;IACG,QAAQ,CAAC,CAAC,EACd,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IA6DhC;;;;OAIG;IACG,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;CA2JpE;AAED,oDAAoD;AACpD,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,CAE9E"}
@@ -0,0 +1,322 @@
1
+ // Repository — entry point. Wraps hologit's Repo with gitsheets-specific
2
+ // orchestration (transactions, sheet discovery). See specs/api/repository.md.
3
+ import { execFile } from 'node:child_process';
4
+ import { promisify } from 'node:util';
5
+ import { Repo as HologitRepo } from 'hologit';
6
+ import { ConfigError, RefError, TransactionError } from './errors.js';
7
+ import { PushDaemon, resolveBackoff, } from './push-daemon.js';
8
+ import { Sheet } from './sheet.js';
9
+ import { Mutex, Transaction, resolveAuthor, transactionContext, } from './transaction.js';
10
+ const exec = promisify(execFile);
11
+ export class Repository {
12
+ #hologitRepo;
13
+ #mutex = new Mutex();
14
+ #postCommitHooks = [];
15
+ #strictMode = false;
16
+ #pushDaemon = null;
17
+ constructor(hologitRepo) {
18
+ this.#hologitRepo = hologitRepo;
19
+ }
20
+ /** Discover a `.git` upward from `cwd` and open it. */
21
+ static async fromCwd() {
22
+ const repo = await HologitRepo.getFromEnvironment();
23
+ return new Repository(repo);
24
+ }
25
+ /** Open a specific git directory. */
26
+ static async open(opts) {
27
+ if (!opts.gitDir) {
28
+ return Repository.fromCwd();
29
+ }
30
+ const repoOpts = { gitDir: opts.gitDir };
31
+ if (opts.workTree !== undefined) {
32
+ repoOpts.workTree = opts.workTree;
33
+ }
34
+ const repo = new HologitRepo(repoOpts);
35
+ return new Repository(repo);
36
+ }
37
+ /**
38
+ * @internal — Direct access to the underlying hologit substrate is reserved
39
+ * for the library. Consumers should use the public Repository surface; the
40
+ * substrate is an implementation detail and will swap to Rust holo-tree in
41
+ * v1.1 with no public-API change ([#127]).
42
+ */
43
+ get hologitRepo() {
44
+ return this.#hologitRepo;
45
+ }
46
+ get gitDir() {
47
+ return this.#hologitRepo.gitDir;
48
+ }
49
+ /** @internal — used by Sheet to enforce strict mode. Library cross-class signal, not a consumer API. */
50
+ isStrictMode() {
51
+ return this.#strictMode;
52
+ }
53
+ /** Switch to strict mode — mutations outside repo.transact throw. One-way. */
54
+ requireExplicitTransactions() {
55
+ this.#strictMode = true;
56
+ }
57
+ /** Resolve a ref or commit hash. Returns the full commit hash or null. */
58
+ async resolveRef(ref) {
59
+ return this.#hologitRepo.resolveRef(ref);
60
+ }
61
+ /**
62
+ * Open a Sheet handle bound to the workspace at the resolved ref (default
63
+ * HEAD). Throws ConfigError(config_missing) when `.gitsheets/<name>.toml`
64
+ * is absent.
65
+ */
66
+ async openSheet(name, opts = {}) {
67
+ const root = opts.root ?? '.';
68
+ const workspace = await this.#getWorkspace();
69
+ const dataTree = await this.#resolveDataTree(workspace, root);
70
+ const configPath = joinTreePath(root, '.gitsheets', `${name}.toml`);
71
+ const sheetOpts = {
72
+ repo: this,
73
+ workspace,
74
+ dataTree,
75
+ name,
76
+ configPath,
77
+ };
78
+ if (opts.validator !== undefined) {
79
+ Object.assign(sheetOpts, { validator: opts.validator });
80
+ }
81
+ const sheet = new Sheet(sheetOpts);
82
+ // Eagerly validate config exists by reading once.
83
+ await sheet.readConfig();
84
+ return sheet;
85
+ }
86
+ /** Discover every sheet declared in `<root>/.gitsheets/*.toml`. */
87
+ async openSheets(opts = {}) {
88
+ const root = opts.root ?? '.';
89
+ const workspace = await this.#getWorkspace();
90
+ const sheetsDir = await workspace.root.getSubtree(joinTreePath(root, '.gitsheets'));
91
+ if (!sheetsDir)
92
+ return {};
93
+ const children = await sheetsDir.getChildren();
94
+ const out = {};
95
+ const dataTree = await this.#resolveDataTree(workspace, root);
96
+ // for...in to include hologit's prototype-loaded entries.
97
+ for (const childName in children) {
98
+ const child = children[childName];
99
+ const match = /^(.+)\.toml$/.exec(childName);
100
+ if (!match)
101
+ continue;
102
+ if (!child || child.isBlob !== true)
103
+ continue;
104
+ const sheetName = match[1];
105
+ out[sheetName] = new Sheet({
106
+ repo: this,
107
+ workspace,
108
+ dataTree,
109
+ name: sheetName,
110
+ configPath: joinTreePath(root, '.gitsheets', childName),
111
+ });
112
+ }
113
+ return out;
114
+ }
115
+ /**
116
+ * Run a handler inside a transaction. On handler success, commit; on throw,
117
+ * discard the tree. See specs/api/transaction.md.
118
+ */
119
+ async transact(opts, handler) {
120
+ if (transactionContext.getStore() !== undefined) {
121
+ throw new TransactionError('transaction_in_progress', 'nested repo.transact is not allowed — use tx.sheet(name) inside the handler');
122
+ }
123
+ const normalized = Transaction.normalizeOptions(opts);
124
+ const author = await resolveAuthor(this.gitDir, normalized.author);
125
+ const committer = normalized.committer ?? author;
126
+ const release = await this.#mutex.acquire();
127
+ try {
128
+ const { parent, branch } = await this.#resolveParent(normalized.parent, normalized.branch);
129
+ const parentCommitHash = parent.commitHash;
130
+ const workspace = parentCommitHash
131
+ ? await this.#hologitRepo.createWorkspaceFromRef(parentCommitHash)
132
+ : await this.#emptyWorkspace();
133
+ const tx = new Transaction({
134
+ hologitRepo: this.#hologitRepo,
135
+ workspace,
136
+ parentCommitHash,
137
+ parentRef: parent.refName,
138
+ branchRef: branch,
139
+ author,
140
+ committer,
141
+ message: normalized.message,
142
+ trailers: normalized.trailers,
143
+ sheetFactory: (name, ws, tree, validator) => this.#makeTxSheet(tx, name, ws, tree, validator),
144
+ });
145
+ let value;
146
+ try {
147
+ value = await transactionContext.run(tx, () => handler(tx));
148
+ }
149
+ catch (err) {
150
+ tx.discard();
151
+ throw err;
152
+ }
153
+ const result = await tx.finalize(value);
154
+ if (result.commitHash !== null) {
155
+ for (const hook of this.#postCommitHooks) {
156
+ try {
157
+ hook(result.commitHash);
158
+ }
159
+ catch {
160
+ // Hooks must not break transactions.
161
+ }
162
+ }
163
+ }
164
+ return result;
165
+ }
166
+ finally {
167
+ release();
168
+ }
169
+ }
170
+ /**
171
+ * Start an async push daemon for this repo. Only one daemon may be active
172
+ * at a time; throws TransactionError(push_daemon_running) on contention.
173
+ * See specs/behaviors/push-sync.md.
174
+ */
175
+ async startPushDaemon(opts) {
176
+ if (this.#pushDaemon) {
177
+ throw new TransactionError('push_daemon_running', 'a push daemon is already running for this Repository — stop it first');
178
+ }
179
+ let branch = opts.branch;
180
+ if (!branch) {
181
+ const headRef = await this.#headBranchRef();
182
+ if (!headRef) {
183
+ throw new RefError('ref_not_found', 'cannot start push daemon — HEAD is detached or the repo is fresh');
184
+ }
185
+ branch = headRef.replace(/^refs\/heads\//, '');
186
+ }
187
+ const daemon = new PushDaemon({
188
+ gitDir: this.gitDir,
189
+ remote: opts.remote,
190
+ branch,
191
+ backoff: resolveBackoff(opts.backoff),
192
+ maxRetries: opts.maxRetries ?? Number.POSITIVE_INFINITY,
193
+ });
194
+ this.#pushDaemon = daemon;
195
+ const hook = (commitHash) => daemon.notifyCommit(commitHash);
196
+ this.#postCommitHooks.push(hook);
197
+ daemon.once('stopped', () => {
198
+ const idx = this.#postCommitHooks.indexOf(hook);
199
+ if (idx >= 0)
200
+ this.#postCommitHooks.splice(idx, 1);
201
+ this.#pushDaemon = null;
202
+ });
203
+ return daemon;
204
+ }
205
+ // --- Private helpers ---
206
+ #makeTxSheet(tx, name, workspace, tree, validator) {
207
+ const configPath = `.gitsheets/${name}.toml`;
208
+ const opts = {
209
+ repo: this,
210
+ workspace,
211
+ dataTree: tree,
212
+ name,
213
+ configPath,
214
+ transaction: tx,
215
+ };
216
+ if (validator !== undefined)
217
+ Object.assign(opts, { validator });
218
+ return new Sheet(opts);
219
+ }
220
+ async #getWorkspace() {
221
+ // Bypass hologit's getWorkspace cache — it caches the first observed
222
+ // workspace per Repo instance, so post-commit reads would return stale
223
+ // state. Resolve HEAD fresh on each call. Fresh-repo fallback handles #19.
224
+ let head = null;
225
+ try {
226
+ head = await this.#hologitRepo.resolveRef('HEAD');
227
+ }
228
+ catch {
229
+ head = null;
230
+ }
231
+ if (head) {
232
+ return this.#hologitRepo.createWorkspaceFromRef(head);
233
+ }
234
+ return this.#emptyWorkspace();
235
+ }
236
+ async #emptyWorkspace() {
237
+ // hologit doesn't expose an empty-workspace factory directly. Use the
238
+ // empty-tree hash to bootstrap a workspace from a deterministic tree.
239
+ const { TreeObject } = await import('hologit');
240
+ const emptyTreeHash = TreeObject.getEmptyTreeHash();
241
+ return this.#hologitRepo.createWorkspaceFromTreeHash(emptyTreeHash);
242
+ }
243
+ async #resolveDataTree(workspace, root) {
244
+ if (root === '.' || root === '')
245
+ return workspace.root;
246
+ const sub = await workspace.root.getSubtree(root, true);
247
+ if (!sub) {
248
+ throw new ConfigError('config_missing', `data root ${root} not found in workspace`);
249
+ }
250
+ return sub;
251
+ }
252
+ /**
253
+ * Resolve the parent ref + branch ref pair per specs/behaviors/transactions.md.
254
+ * - parent unset → HEAD's branch (or detached HEAD's commit)
255
+ * - parent = branch → branch advances
256
+ * - parent = hash → no ref updated unless `branch` explicit
257
+ */
258
+ async #resolveParent(parent, branch) {
259
+ if (!parent) {
260
+ // Use HEAD's branch when on a branch; otherwise current HEAD commit.
261
+ const headRef = await this.#headBranchRef();
262
+ if (headRef) {
263
+ const commit = await this.#hologitRepo.resolveRef(headRef);
264
+ return {
265
+ parent: { refName: headRef, commitHash: commit },
266
+ branch: branch ?? headRef,
267
+ };
268
+ }
269
+ // Detached or fresh repo
270
+ const headHash = await this.#hologitRepo.resolveRef('HEAD').catch(() => null);
271
+ return {
272
+ parent: { refName: null, commitHash: headHash },
273
+ branch: branch ?? null,
274
+ };
275
+ }
276
+ // parent is set — figure out if it's a ref name (branch) or a hash
277
+ const isLikelyBranch = /^[a-zA-Z0-9_./-]+$/.test(parent) && !/^[0-9a-f]{4,40}$/.test(parent);
278
+ if (isLikelyBranch) {
279
+ const refName = parent.startsWith('refs/') ? parent : `refs/heads/${parent}`;
280
+ const commit = await this.#hologitRepo.resolveRef(refName);
281
+ if (commit === null) {
282
+ // Maybe they passed a raw "main" that doesn't exist yet
283
+ throw new RefError('ref_not_found', `ref not found: ${parent}`);
284
+ }
285
+ return {
286
+ parent: { refName, commitHash: commit },
287
+ branch: branch ?? refName,
288
+ };
289
+ }
290
+ // Hash
291
+ const resolved = await this.#hologitRepo.resolveRef(parent);
292
+ if (!resolved) {
293
+ throw new RefError('ref_not_found', `cannot resolve commit: ${parent}`);
294
+ }
295
+ return {
296
+ parent: { refName: null, commitHash: resolved },
297
+ branch: branch ? (branch.startsWith('refs/') ? branch : `refs/heads/${branch}`) : null,
298
+ };
299
+ }
300
+ async #headBranchRef() {
301
+ try {
302
+ const { stdout } = await exec('git', ['symbolic-ref', '--quiet', 'HEAD'], {
303
+ cwd: this.gitDir,
304
+ });
305
+ return stdout.trim() || null;
306
+ }
307
+ catch {
308
+ return null;
309
+ }
310
+ }
311
+ }
312
+ /** Convenience factory: `openRepo({ gitDir? })`. */
313
+ export async function openRepo(opts = {}) {
314
+ return Repository.open(opts);
315
+ }
316
+ function joinTreePath(...parts) {
317
+ return parts
318
+ .map((p) => p.replace(/^\/+/, '').replace(/\/+$/, ''))
319
+ .filter((p) => p.length > 0 && p !== '.')
320
+ .join('/');
321
+ }
322
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ import type { BlobObject, TreeObject, Workspace } from 'hologit';
2
+ import { type RecordLike } from './path-template/index.js';
3
+ import type { Repository } from './repository.js';
4
+ import { Transaction } from './transaction.js';
5
+ import { type JSONSchema, type StandardSchemaV1 } from './validation.js';
6
+ export declare const RECORD_SHEET_KEY: unique symbol;
7
+ export declare const RECORD_PATH_KEY: unique symbol;
8
+ export type SortRule = boolean | readonly string[] | Readonly<Record<string, 'ASC' | 'DESC'>> | string;
9
+ export interface SheetFieldConfig {
10
+ /** Optional sort rule for array-valued fields (canonical normalization). */
11
+ readonly sort?: SortRule;
12
+ }
13
+ export interface SheetConfig {
14
+ readonly root: string;
15
+ readonly path: string;
16
+ readonly fields: Readonly<Record<string, SheetFieldConfig>>;
17
+ /** JSON Schema for record validation; null if no [gitsheet.schema] block. */
18
+ readonly schema: JSONSchema | null;
19
+ }
20
+ export interface UpsertResult {
21
+ readonly blob: BlobObject;
22
+ readonly path: string;
23
+ }
24
+ /**
25
+ * Filter passed to `Sheet.query` / `queryFirst` / `queryAll`. Each field's
26
+ * value can be a literal (equality match) or a predicate function. When `T`
27
+ * is `Record<string, unknown>` (the default), arbitrary string keys are
28
+ * accepted; consumer-supplied `T` narrows to its own keys.
29
+ */
30
+ export type QueryFilter<T extends RecordLike = RecordLike> = {
31
+ [K in keyof T]?: T[K] | ((value: T[K], record: T) => unknown);
32
+ };
33
+ export type IndexKeyFn<T extends RecordLike = RecordLike> = (record: T) => string | undefined | null;
34
+ export interface DefineIndexOptions {
35
+ readonly unique?: boolean;
36
+ readonly eager?: boolean;
37
+ }
38
+ export interface SheetConstructorOptions<T extends RecordLike = RecordLike> {
39
+ readonly repo: Repository;
40
+ readonly workspace: Workspace;
41
+ readonly dataTree: TreeObject;
42
+ readonly name: string;
43
+ readonly configPath: string;
44
+ readonly transaction?: Transaction;
45
+ /** Consumer-supplied Standard Schema validator; runs after JSON Schema. */
46
+ readonly validator?: StandardSchemaV1<unknown, T>;
47
+ }
48
+ export declare class Sheet<T extends RecordLike = RecordLike> {
49
+ #private;
50
+ constructor(opts: SheetConstructorOptions<T>);
51
+ get name(): string;
52
+ get configPath(): string;
53
+ /** True if this Sheet is bound to a transaction's private tree. */
54
+ get isTransactionBound(): boolean;
55
+ readConfig(): Promise<SheetConfig>;
56
+ /** Same as readConfig — config is cached by config-blob hash anyway. */
57
+ getCachedConfig(): Promise<SheetConfig>;
58
+ /** Async iterator over records matching the filter. */
59
+ query(filter?: QueryFilter<T>): AsyncGenerator<T>;
60
+ queryFirst(filter?: QueryFilter<T>): Promise<T | undefined>;
61
+ queryAll(filter?: QueryFilter<T>): Promise<T[]>;
62
+ pathForRecord(record: T): Promise<string>;
63
+ /**
64
+ * Apply canonical normalization (deep key sort + array-field sort rules)
65
+ * without writing or validating.
66
+ */
67
+ normalizeRecord(record: T): Promise<T>;
68
+ clear(): Promise<void>;
69
+ clone(): Promise<Sheet<T>>;
70
+ upsert(record: T): Promise<UpsertResult>;
71
+ /**
72
+ * RFC 7396 JSON Merge Patch. Reads the matching record, merges `partial`,
73
+ * validates, and upserts the result. Returns the same shape as upsert.
74
+ * Throws NotFoundError if the query matches no record.
75
+ */
76
+ patch(query: QueryFilter<T>, partial: Partial<T>): Promise<UpsertResult>;
77
+ delete(target: T | string): Promise<void>;
78
+ /**
79
+ * Declare a secondary in-memory index on this Sheet.
80
+ *
81
+ * Overloads:
82
+ * defineIndex(name, keyFn) → void
83
+ * defineIndex(name, { unique?, eager?: false }, keyFn) → void
84
+ * defineIndex(name, { unique?, eager: true }, keyFn) → Promise<void>
85
+ *
86
+ * keyFn returns a string key; returning undefined / null excludes the
87
+ * record from the index entirely. With `eager: true`, the return value
88
+ * resolves when the initial build completes (or rejects on conflict).
89
+ */
90
+ defineIndex(name: string, keyFn: IndexKeyFn<T>): void;
91
+ defineIndex(name: string, opts: DefineIndexOptions & {
92
+ eager: true;
93
+ }, keyFn: IndexKeyFn<T>): Promise<void>;
94
+ defineIndex(name: string, opts: DefineIndexOptions & {
95
+ eager?: false | undefined;
96
+ }, keyFn: IndexKeyFn<T>): void;
97
+ /**
98
+ * Look up records by an index. Unique indexes return `record | undefined`;
99
+ * non-unique indexes return an array.
100
+ */
101
+ findByIndex(name: string, key: string): Promise<T | T[] | undefined>;
102
+ getAttachment(record: T | string, name: string): Promise<BlobObject | null>;
103
+ getAttachments(record: T | string): Promise<Record<string, BlobObject> | null>;
104
+ setAttachment(record: T | string, name: string, blob: string | BlobObject): Promise<void>;
105
+ setAttachments(record: T | string, attachments: Record<string, string | BlobObject>): Promise<void>;
106
+ }
107
+ //# sourceMappingURL=sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../src/sheet.ts"],"names":[],"mappings":"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"}