@arden-hq/revisions 0.0.0-stage → 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +84 -2
  3. package/dist/domain/change-set.d.ts +34 -0
  4. package/dist/domain/change-set.d.ts.map +1 -0
  5. package/dist/domain/change-set.js +206 -0
  6. package/dist/domain/change-set.js.map +1 -0
  7. package/dist/domain/codec.d.ts +17 -0
  8. package/dist/domain/codec.d.ts.map +1 -0
  9. package/dist/domain/codec.js +188 -0
  10. package/dist/domain/codec.js.map +1 -0
  11. package/dist/domain/errors.d.ts +61 -0
  12. package/dist/domain/errors.d.ts.map +1 -0
  13. package/dist/domain/errors.js +44 -0
  14. package/dist/domain/errors.js.map +1 -0
  15. package/dist/domain/format.d.ts +72 -0
  16. package/dist/domain/format.d.ts.map +1 -0
  17. package/dist/domain/format.js +93 -0
  18. package/dist/domain/format.js.map +1 -0
  19. package/dist/domain/integrity.d.ts +7 -0
  20. package/dist/domain/integrity.d.ts.map +1 -0
  21. package/dist/domain/integrity.js +100 -0
  22. package/dist/domain/integrity.js.map +1 -0
  23. package/dist/domain/model.d.ts +114 -0
  24. package/dist/domain/model.d.ts.map +1 -0
  25. package/dist/domain/model.js +145 -0
  26. package/dist/domain/model.js.map +1 -0
  27. package/dist/domain/query.d.ts +31 -0
  28. package/dist/domain/query.d.ts.map +1 -0
  29. package/dist/domain/query.js +168 -0
  30. package/dist/domain/query.js.map +1 -0
  31. package/dist/domain/transaction.d.ts +26 -0
  32. package/dist/domain/transaction.d.ts.map +1 -0
  33. package/dist/domain/transaction.js +93 -0
  34. package/dist/domain/transaction.js.map +1 -0
  35. package/dist/domain/tree.d.ts +6 -0
  36. package/dist/domain/tree.d.ts.map +1 -0
  37. package/dist/domain/tree.js +59 -0
  38. package/dist/domain/tree.js.map +1 -0
  39. package/dist/effect/index.d.ts +10 -0
  40. package/dist/effect/index.d.ts.map +1 -0
  41. package/dist/effect/index.js +4 -0
  42. package/dist/effect/index.js.map +1 -0
  43. package/dist/repository/commit.d.ts +12 -0
  44. package/dist/repository/commit.d.ts.map +1 -0
  45. package/dist/repository/commit.js +164 -0
  46. package/dist/repository/commit.js.map +1 -0
  47. package/dist/repository/history.d.ts +21 -0
  48. package/dist/repository/history.d.ts.map +1 -0
  49. package/dist/repository/history.js +152 -0
  50. package/dist/repository/history.js.map +1 -0
  51. package/dist/repository/service.d.ts +114 -0
  52. package/dist/repository/service.d.ts.map +1 -0
  53. package/dist/repository/service.js +374 -0
  54. package/dist/repository/service.js.map +1 -0
  55. package/dist/repository/state.d.ts +27 -0
  56. package/dist/repository/state.d.ts.map +1 -0
  57. package/dist/repository/state.js +72 -0
  58. package/dist/repository/state.js.map +1 -0
  59. package/dist/repository/transaction.d.ts +27 -0
  60. package/dist/repository/transaction.d.ts.map +1 -0
  61. package/dist/repository/transaction.js +372 -0
  62. package/dist/repository/transaction.js.map +1 -0
  63. package/dist/storage/files.d.ts +17 -0
  64. package/dist/storage/files.d.ts.map +1 -0
  65. package/dist/storage/files.js +179 -0
  66. package/dist/storage/files.js.map +1 -0
  67. package/dist/storage/maintenance-adapter.d.ts +5 -0
  68. package/dist/storage/maintenance-adapter.d.ts.map +1 -0
  69. package/dist/storage/maintenance-adapter.js +177 -0
  70. package/dist/storage/maintenance-adapter.js.map +1 -0
  71. package/dist/storage/maintenance-reader.d.ts +17 -0
  72. package/dist/storage/maintenance-reader.d.ts.map +1 -0
  73. package/dist/storage/maintenance-reader.js +82 -0
  74. package/dist/storage/maintenance-reader.js.map +1 -0
  75. package/dist/storage/maintenance.d.ts +113 -0
  76. package/dist/storage/maintenance.d.ts.map +1 -0
  77. package/dist/storage/maintenance.js +445 -0
  78. package/dist/storage/maintenance.js.map +1 -0
  79. package/dist/storage/node.d.ts +7 -0
  80. package/dist/storage/node.d.ts.map +1 -0
  81. package/dist/storage/node.js +53 -0
  82. package/dist/storage/node.js.map +1 -0
  83. package/dist/storage/service.d.ts +88 -0
  84. package/dist/storage/service.d.ts.map +1 -0
  85. package/dist/storage/service.js +506 -0
  86. package/dist/storage/service.js.map +1 -0
  87. package/package.json +63 -4
@@ -0,0 +1,114 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { InvalidRevisionInputError, UnsafePathError } from "./errors.js";
3
+ /** The only states represented by a resource version. */
4
+ export declare const ResourceState: Schema.Union<readonly [Schema.Literal<"active">, Schema.Literal<"archived">]>;
5
+ export type ResourceState = typeof ResourceState.Type;
6
+ declare const ResourceVersion_base: Schema.Class<ResourceVersion, Schema.Struct<{
7
+ readonly resourceId: Schema.String;
8
+ readonly path: Schema.String;
9
+ readonly blobId: Schema.String;
10
+ readonly state: Schema.Union<readonly [Schema.Literal<"active">, Schema.Literal<"archived">]>;
11
+ readonly versionId: Schema.String;
12
+ }>, {}>;
13
+ /** A normalized, immutable resource version. */
14
+ export declare class ResourceVersion extends ResourceVersion_base {
15
+ }
16
+ declare const WorkingTreeChange_base: Schema.Class<WorkingTreeChange, Schema.Struct<{
17
+ readonly resourceId: Schema.String;
18
+ readonly path: Schema.String;
19
+ readonly expectedVersion: Schema.String;
20
+ readonly content: Schema.Uint8Array;
21
+ }>, {}>;
22
+ /** Exact bytes observed for one externally changed active resource. */
23
+ export declare class WorkingTreeChange extends WorkingTreeChange_base {
24
+ }
25
+ declare const WorkingTreeAdoption_base: Schema.Class<WorkingTreeAdoption, Schema.Struct<{
26
+ readonly expectedHead: Schema.NullOr<Schema.String>;
27
+ readonly changes: Schema.$Array<typeof WorkingTreeChange>;
28
+ readonly actor: Schema.String;
29
+ readonly origin: Schema.String;
30
+ readonly reason: Schema.String;
31
+ readonly idempotencyKey: Schema.String;
32
+ }>, {}>;
33
+ /** A guarded request to publish already-materialized working-tree changes. */
34
+ export declare class WorkingTreeAdoption extends WorkingTreeAdoption_base {
35
+ }
36
+ declare const Create_base: Schema.Class<Create, Schema.TaggedStruct<"Create", {
37
+ readonly resourceId: Schema.String;
38
+ readonly path: Schema.String;
39
+ readonly content: Schema.Uint8Array;
40
+ }>, {}>;
41
+ /** A newly created resource. */
42
+ export declare class Create extends Create_base {
43
+ }
44
+ declare const Update_base: Schema.Class<Update, Schema.TaggedStruct<"Update", {
45
+ readonly resourceId: Schema.String;
46
+ readonly expectedVersion: Schema.String;
47
+ readonly content: Schema.Uint8Array;
48
+ }>, {}>;
49
+ /** A replacement guarded by an exact previous version. */
50
+ export declare class Update extends Update_base {
51
+ }
52
+ declare const Move_base: Schema.Class<Move, Schema.TaggedStruct<"Move", {
53
+ readonly resourceId: Schema.String;
54
+ readonly expectedVersion: Schema.String;
55
+ readonly path: Schema.String;
56
+ readonly content: Schema.optionalKey<Schema.Uint8Array>;
57
+ }>, {}>;
58
+ declare class Move extends Move_base {
59
+ }
60
+ declare const Archive_base: Schema.Class<Archive, Schema.TaggedStruct<"Archive", {
61
+ readonly resourceId: Schema.String;
62
+ readonly expectedVersion: Schema.String;
63
+ }>, {}>;
64
+ declare class Archive extends Archive_base {
65
+ }
66
+ declare const Restore_base: Schema.Class<Restore, Schema.TaggedStruct<"Restore", {
67
+ readonly resourceId: Schema.String;
68
+ readonly expectedVersion: Schema.String;
69
+ readonly path: Schema.optionalKey<Schema.String>;
70
+ readonly content: Schema.optionalKey<Schema.Uint8Array>;
71
+ }>, {}>;
72
+ /** Re-activates an archived resource, optionally changing path/content. */
73
+ export declare class Restore extends Restore_base {
74
+ }
75
+ export declare const Operation: Schema.Union<readonly [typeof Create, typeof Update, typeof Move, typeof Archive, typeof Restore]>;
76
+ export type Operation = typeof Operation.Type;
77
+ declare const ChangeSet_base: Schema.Class<ChangeSet, Schema.Struct<{
78
+ readonly operations: Schema.$Array<Schema.Union<readonly [typeof Create, typeof Update, typeof Move, typeof Archive, typeof Restore]>>;
79
+ readonly actor: Schema.String;
80
+ readonly origin: Schema.String;
81
+ readonly reason: Schema.String;
82
+ readonly idempotencyKey: Schema.String;
83
+ readonly expectedHead: Schema.optionalKey<Schema.NullOr<Schema.String>>;
84
+ readonly enforceExpectedHead: Schema.optionalKey<Schema.Boolean>;
85
+ }>, {}>;
86
+ /** A validated immutable request submitted to the repository boundary. */
87
+ export declare class ChangeSet extends ChangeSet_base {
88
+ }
89
+ declare const ResourceChange_base: Schema.Class<ResourceChange, Schema.Struct<{
90
+ readonly action: Schema.String;
91
+ readonly before: Schema.NullOr<typeof ResourceVersion>;
92
+ readonly after: Schema.NullOr<typeof ResourceVersion>;
93
+ }>, {}>;
94
+ export declare class ResourceChange extends ResourceChange_base {
95
+ }
96
+ declare const Commit_base: Schema.Class<Commit, Schema.Struct<{
97
+ readonly commitId: Schema.String;
98
+ readonly parentId: Schema.NullOr<Schema.String>;
99
+ readonly treeId: Schema.String;
100
+ readonly actor: Schema.String;
101
+ readonly origin: Schema.String;
102
+ readonly reason: Schema.String;
103
+ readonly timestamp: Schema.String;
104
+ readonly changes: Schema.$Array<typeof ResourceChange>;
105
+ }>, {}>;
106
+ /** A parsed immutable commit. Timestamp is kept as canonical text to retain microseconds. */
107
+ export declare class Commit extends Commit_base {
108
+ }
109
+ /** Validate and return an already-normalized POSIX-relative managed path. */
110
+ export declare const normalizeRelativePath: (value: string) => Effect.Effect<string, UnsafePathError, never>;
111
+ /** Build the canonical version token from an immutable resource identity. */
112
+ export declare const makeVersion: (resourceId: string, path: string, blobId: string, state: "active" | "archived", previousVersionId?: string | null | undefined) => Effect.Effect<ResourceVersion, InvalidRevisionInputError | UnsafePathError, never>;
113
+ export {};
114
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/domain/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAOxE,yDAAyD;AACzD,eAAO,MAAM,aAAa,+EAAuE,CAAA;AACjG,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAA;;;;;;;;AAErD,gDAAgD;AAChD,qBAAa,eAAgB,SAAQ,oBAQnC;CAAG;;;;;;;AAEL,uEAAuE;AACvE,qBAAa,iBAAkB,SAAQ,sBAOrC;CAAG;;;;;;;;;AAEL,8EAA8E;AAC9E,qBAAa,mBAAoB,SAAQ,wBASvC;CAAG;;;;;;AAEL,gCAAgC;AAChC,qBAAa,MAAO,SAAQ,WAI1B;CAAG;;;;;;AAEL,0DAA0D;AAC1D,qBAAa,MAAO,SAAQ,WAI1B;CAAG;;;;;;;AAEL,cAAM,IAAK,SAAQ,SAKjB;CAAG;;;;;AAEL,cAAM,OAAQ,SAAQ,YAGpB;CAAG;;;;;;;AAEL,2EAA2E;AAC3E,qBAAa,OAAQ,SAAQ,YAK3B;CAAG;AAEL,eAAO,MAAM,SAAS,oGAAyD,CAAA;AAC/E,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA;;;;;;;;;;AAE7C,0EAA0E;AAC1E,qBAAa,SAAU,SAAQ,cAQ7B;CAAG;;;;;;AAEL,qBAAa,cAAe,SAAQ,mBAIlC;CAAG;;;;;;;;;;;AAEL,6FAA6F;AAC7F,qBAAa,MAAO,SAAQ,WAS1B;CAAG;AAEL,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,kEAmBhC,CAAA;AAEF,6EAA6E;AAC7E,eAAO,MAAM,WAAW,uNAgDtB,CAAA"}
@@ -0,0 +1,145 @@
1
+ import { posix, win32 } from "node:path";
2
+ import { Effect, Schema } from "effect";
3
+ import { InvalidRevisionInputError, UnsafePathError } from "./errors.js";
4
+ import { canonicalJsonl } from "./format.js";
5
+ import { sha256Hex } from "@arden-hq/std/hash";
6
+ const NonEmptyText = Schema.String.check(Schema.isMinLength(1));
7
+ const Hash = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/));
8
+ /** The only states represented by a resource version. */
9
+ export const ResourceState = Schema.Union([Schema.Literal("active"), Schema.Literal("archived")]);
10
+ /** A normalized, immutable resource version. */
11
+ export class ResourceVersion extends Schema.Class("arden/revisions/ResourceVersion")({
12
+ resourceId: NonEmptyText,
13
+ path: NonEmptyText,
14
+ blobId: Hash,
15
+ state: ResourceState,
16
+ versionId: Hash
17
+ }) {
18
+ }
19
+ /** Exact bytes observed for one externally changed active resource. */
20
+ export class WorkingTreeChange extends Schema.Class("arden/revisions/WorkingTreeChange")({
21
+ resourceId: NonEmptyText,
22
+ path: NonEmptyText,
23
+ expectedVersion: Hash,
24
+ content: Schema.Uint8Array
25
+ }) {
26
+ }
27
+ /** A guarded request to publish already-materialized working-tree changes. */
28
+ export class WorkingTreeAdoption extends Schema.Class("arden/revisions/WorkingTreeAdoption")({
29
+ expectedHead: Schema.NullOr(Hash),
30
+ changes: Schema.Array(WorkingTreeChange).check(Schema.isMinLength(1)),
31
+ actor: NonEmptyText,
32
+ origin: NonEmptyText,
33
+ reason: NonEmptyText,
34
+ idempotencyKey: NonEmptyText
35
+ }) {
36
+ }
37
+ /** A newly created resource. */
38
+ export class Create extends Schema.TaggedClass()("Create", {
39
+ resourceId: NonEmptyText,
40
+ path: NonEmptyText,
41
+ content: Schema.Uint8Array
42
+ }) {
43
+ }
44
+ /** A replacement guarded by an exact previous version. */
45
+ export class Update extends Schema.TaggedClass()("Update", {
46
+ resourceId: NonEmptyText,
47
+ expectedVersion: Hash,
48
+ content: Schema.Uint8Array
49
+ }) {
50
+ }
51
+ class Move extends Schema.TaggedClass()("Move", {
52
+ resourceId: NonEmptyText,
53
+ expectedVersion: Hash,
54
+ path: NonEmptyText,
55
+ content: Schema.optionalKey(Schema.Uint8Array)
56
+ }) {
57
+ }
58
+ class Archive extends Schema.TaggedClass()("Archive", {
59
+ resourceId: NonEmptyText,
60
+ expectedVersion: Hash
61
+ }) {
62
+ }
63
+ /** Re-activates an archived resource, optionally changing path/content. */
64
+ export class Restore extends Schema.TaggedClass()("Restore", {
65
+ resourceId: NonEmptyText,
66
+ expectedVersion: Hash,
67
+ path: Schema.optionalKey(NonEmptyText),
68
+ content: Schema.optionalKey(Schema.Uint8Array)
69
+ }) {
70
+ }
71
+ export const Operation = Schema.Union([Create, Update, Move, Archive, Restore]);
72
+ /** A validated immutable request submitted to the repository boundary. */
73
+ export class ChangeSet extends Schema.Class("arden/revisions/ChangeSet")({
74
+ operations: Schema.Array(Operation).check(Schema.isMinLength(1)),
75
+ actor: NonEmptyText,
76
+ origin: NonEmptyText,
77
+ reason: NonEmptyText,
78
+ idempotencyKey: NonEmptyText,
79
+ expectedHead: Schema.optionalKey(Schema.NullOr(Hash)),
80
+ enforceExpectedHead: Schema.optionalKey(Schema.Boolean)
81
+ }) {
82
+ }
83
+ export class ResourceChange extends Schema.Class("arden/revisions/ResourceChange")({
84
+ action: NonEmptyText,
85
+ before: Schema.NullOr(ResourceVersion),
86
+ after: Schema.NullOr(ResourceVersion)
87
+ }) {
88
+ }
89
+ /** A parsed immutable commit. Timestamp is kept as canonical text to retain microseconds. */
90
+ export class Commit extends Schema.Class("arden/revisions/Commit")({
91
+ commitId: Hash,
92
+ parentId: Schema.NullOr(Hash),
93
+ treeId: Hash,
94
+ actor: NonEmptyText,
95
+ origin: NonEmptyText,
96
+ reason: NonEmptyText,
97
+ timestamp: NonEmptyText,
98
+ changes: Schema.Array(ResourceChange).check(Schema.isMinLength(1))
99
+ }) {
100
+ }
101
+ /** Validate and return an already-normalized POSIX-relative managed path. */
102
+ export const normalizeRelativePath = Effect.fn("normalizeRelativePath")(function* (value) {
103
+ const normalized = posix.normalize(value);
104
+ const parts = value.split(posix.sep);
105
+ const invalid = value.length === 0 ||
106
+ value.includes("\u0000") ||
107
+ value.includes("\\") ||
108
+ posix.isAbsolute(value) ||
109
+ win32.isAbsolute(value) ||
110
+ normalized !== value ||
111
+ parts.some((part) => part.length === 0 || part === "." || part === "..");
112
+ if (invalid) {
113
+ return yield* new UnsafePathError({
114
+ message: `managed path must be normalized and relative: ${value}`
115
+ });
116
+ }
117
+ return normalized;
118
+ });
119
+ /** Build the canonical version token from an immutable resource identity. */
120
+ export const makeVersion = Effect.fn("makeVersion")(function* (resourceId, path, blobId, state, previousVersionId = null) {
121
+ const normalizedPath = yield* normalizeRelativePath(path);
122
+ const validResourceId = yield* Schema.decodeUnknownEffect(NonEmptyText)(resourceId).pipe(Effect.mapError(() => new InvalidRevisionInputError({ message: "resourceId must not be empty" })));
123
+ const validBlobId = yield* Schema.decodeUnknownEffect(Hash)(blobId).pipe(Effect.mapError(() => new InvalidRevisionInputError({ message: "blobId must be a SHA-256 identifier" })));
124
+ const validState = yield* Schema.decodeUnknownEffect(ResourceState)(state).pipe(Effect.mapError(() => new InvalidRevisionInputError({ message: "state must be active or archived" })));
125
+ const validPreviousId = previousVersionId === null
126
+ ? null
127
+ : yield* Schema.decodeUnknownEffect(Hash)(previousVersionId).pipe(Effect.mapError(() => new InvalidRevisionInputError({
128
+ message: "previousVersionId must be a SHA-256 identifier"
129
+ })));
130
+ const identity = {
131
+ blob_id: validBlobId,
132
+ path: normalizedPath,
133
+ previous_version_id: validPreviousId,
134
+ resource_id: validResourceId,
135
+ state: validState
136
+ };
137
+ return new ResourceVersion({
138
+ resourceId: validResourceId,
139
+ path: normalizedPath,
140
+ blobId: validBlobId,
141
+ state: validState,
142
+ versionId: sha256Hex(canonicalJsonl(identity))
143
+ });
144
+ });
145
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/domain/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { Effect } from "effect";
2
+ import type { ResourceSnapshot } from "./change-set.js";
3
+ import { ResourceVersion } from "./model.js";
4
+ import type { RevisionError } from "./errors.js";
5
+ export interface ResourceDiff {
6
+ readonly resourceId: string;
7
+ readonly before: ResourceVersion | null;
8
+ readonly after: ResourceVersion | null;
9
+ readonly unifiedDiff: string;
10
+ }
11
+ export interface ResourceDiffPage {
12
+ readonly resourceId: string;
13
+ readonly before: ResourceVersion | null;
14
+ readonly after: ResourceVersion | null;
15
+ readonly offset: number;
16
+ readonly endOffset: number;
17
+ readonly hasMore: boolean;
18
+ readonly unifiedDiff: string;
19
+ }
20
+ export interface UnifiedDiffPage {
21
+ readonly offset: number;
22
+ readonly endOffset: number;
23
+ readonly hasMore: boolean;
24
+ readonly text: string;
25
+ }
26
+ export type BlobReader = (blobId: string) => Effect.Effect<Uint8Array, RevisionError>;
27
+ export type BlobSizer = (blobId: string) => Effect.Effect<number, RevisionError>;
28
+ export declare const diff: (before: ResourceSnapshot, after: ResourceSnapshot, resourceIds: Iterable<string> | null | undefined, readBlob: BlobReader) => Effect.Effect<readonly ResourceDiff[], RevisionError, never>;
29
+ export declare const diffPage: (before: ResourceVersion | null, after: ResourceVersion | null, resourceId: string, offset: number, limit: number, tail: boolean, readBlob: BlobReader) => Effect.Effect<ResourceDiffPage, RevisionError, never>;
30
+ export declare const diffVersionsPage: (before: ResourceVersion | null, after: ResourceVersion | null, offset: number, limit: number, tail: boolean, sourceByteLimit: number | null | undefined, blobSize: BlobSizer, readBlob: BlobReader) => Effect.Effect<ResourceDiffPage, RevisionError, never>;
31
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/domain/query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAM5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IACvC,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IACvC,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;AACrF,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;AA4HhF,eAAO,MAAM,IAAI,6LAwCf,CAAA;AAEF,eAAO,MAAM,QAAQ,kNAgCnB,CAAA;AAEF,eAAO,MAAM,gBAAgB,+PAqD3B,CAAA"}
@@ -0,0 +1,168 @@
1
+ import { structuredPatch } from "diff";
2
+ import { Effect } from "effect";
3
+ import { ResourceVersion } from "./model.js";
4
+ import { CorruptRepositoryError, InvalidRevisionInputError, RevisionContentLimitError } from "./errors.js";
5
+ import { compareCodePoints } from "@arden-hq/std/json";
6
+ const failInput = (message) => Effect.fail(new InvalidRevisionInputError({ message }));
7
+ const resourceVersionEqual = (left, right) => left === right ||
8
+ (left !== null &&
9
+ right !== null &&
10
+ left.resourceId === right.resourceId &&
11
+ left.path === right.path &&
12
+ left.blobId === right.blobId &&
13
+ left.state === right.state &&
14
+ left.versionId === right.versionId);
15
+ const diffDecoder = new TextDecoder("utf-8");
16
+ const unifiedRange = (start, count) => {
17
+ if (count === 0)
18
+ return `${start - 1},0`;
19
+ if (count === 1)
20
+ return `${start}`;
21
+ return `${start},${count}`;
22
+ };
23
+ const unifiedDiffChunks = (before, after, oldLabel, newLabel) => {
24
+ const patch = structuredPatch(oldLabel, newLabel, diffDecoder.decode(before), diffDecoder.decode(after), undefined, undefined, { context: 3 });
25
+ if (patch.hunks.length === 0)
26
+ return [];
27
+ const chunks = [`--- ${oldLabel}\n`, `+++ ${newLabel}\n`];
28
+ for (const hunk of patch.hunks) {
29
+ chunks.push(`@@ -${unifiedRange(hunk.oldStart, hunk.oldLines)} +${unifiedRange(hunk.newStart, hunk.newLines)} @@\n`);
30
+ for (const line of hunk.lines)
31
+ chunks.push(`${line}\n`);
32
+ }
33
+ return chunks;
34
+ };
35
+ const unifiedDiff = (before, after, oldLabel, newLabel) => unifiedDiffChunks(before, after, oldLabel, newLabel).join("");
36
+ const codePoints = (value) => Array.from(value);
37
+ const renderPage = Effect.fn("renderPage")(function* (chunks, offset, limit, tail) {
38
+ const points = codePoints(chunks.join(""));
39
+ if (tail) {
40
+ const pageOffset = points.length === 0 ? 0 : Math.floor((points.length - 1) / limit) * limit;
41
+ return {
42
+ offset: pageOffset,
43
+ endOffset: points.length,
44
+ hasMore: false,
45
+ text: points.slice(pageOffset).join("")
46
+ };
47
+ }
48
+ if (offset > points.length || (offset === points.length && offset > 0)) {
49
+ return yield* failInput("offset is outside the resource diff");
50
+ }
51
+ const endOffset = Math.min(points.length, offset + limit);
52
+ return {
53
+ offset,
54
+ endOffset,
55
+ hasMore: endOffset < points.length,
56
+ text: points.slice(offset, endOffset).join("")
57
+ };
58
+ });
59
+ const validatePageArguments = Effect.fn("validatePageArguments")(function* (resourceId, offset, limit, tail) {
60
+ if (typeof resourceId !== "string" || resourceId.length === 0)
61
+ return yield* failInput("resource_id must be a nonempty string");
62
+ if (!Number.isInteger(offset) || offset < 0)
63
+ return yield* failInput("offset must be a nonnegative integer");
64
+ if (!Number.isInteger(limit) || limit <= 0)
65
+ return yield* failInput("limit must be a positive integer");
66
+ if (typeof tail !== "boolean")
67
+ return yield* failInput("tail must be a bool");
68
+ if (tail && offset !== 0)
69
+ return yield* failInput("offset must be zero when tail is requested");
70
+ });
71
+ const unifiedDiffPage = Effect.fn("unifiedDiffPage")(function* (before, after, oldLabel, newLabel, offset, limit, tail) {
72
+ yield* validatePageArguments("diff", offset, limit, tail);
73
+ return yield* renderPage(unifiedDiffChunks(before, after, oldLabel, newLabel), offset, limit, tail);
74
+ });
75
+ export const diff = Effect.fn("diff")(function* (before, after, resourceIds, readBlob) {
76
+ let selected = null;
77
+ if (resourceIds !== null && resourceIds !== undefined) {
78
+ if (typeof resourceIds === "string" || resourceIds instanceof Uint8Array) {
79
+ return yield* failInput("resource_ids must be an iterable of resource IDs");
80
+ }
81
+ const values = [...resourceIds];
82
+ if (!values.every((resourceId) => typeof resourceId === "string" && resourceId.length > 0)) {
83
+ return yield* failInput("resource_ids must contain only nonempty strings");
84
+ }
85
+ selected = new Set(values);
86
+ }
87
+ const changedIds = new Set([...before.keys(), ...after.keys()]);
88
+ const result = [];
89
+ for (const resourceId of [...changedIds].sort(compareCodePoints)) {
90
+ if (selected !== null && !selected.has(resourceId))
91
+ continue;
92
+ const old = before.get(resourceId) ?? null;
93
+ const next = after.get(resourceId) ?? null;
94
+ if (resourceVersionEqual(old, next))
95
+ continue;
96
+ const oldContent = old === null ? new Uint8Array() : yield* readBlob(old.blobId);
97
+ const newContent = next === null ? new Uint8Array() : yield* readBlob(next.blobId);
98
+ result.push({
99
+ resourceId,
100
+ before: old,
101
+ after: next,
102
+ unifiedDiff: unifiedDiff(oldContent, newContent, old?.path ?? "/dev/null", next?.path ?? "/dev/null")
103
+ });
104
+ }
105
+ return result;
106
+ });
107
+ export const diffPage = Effect.fn("diffPage")(function* (before, after, resourceId, offset, limit, tail, readBlob) {
108
+ yield* validatePageArguments(resourceId, offset, limit, tail);
109
+ if (resourceVersionEqual(before, after))
110
+ return yield* failInput(`resource did not change between revisions: ${resourceId}`);
111
+ const oldContent = before === null ? new Uint8Array() : yield* readBlob(before.blobId);
112
+ const newContent = after === null ? new Uint8Array() : yield* readBlob(after.blobId);
113
+ const page = yield* unifiedDiffPage(oldContent, newContent, before?.path ?? "/dev/null", after?.path ?? "/dev/null", offset, limit, tail);
114
+ return {
115
+ resourceId,
116
+ before,
117
+ after,
118
+ offset: page.offset,
119
+ endOffset: page.endOffset,
120
+ hasMore: page.hasMore,
121
+ unifiedDiff: page.text
122
+ };
123
+ });
124
+ export const diffVersionsPage = Effect.fn("diffVersionsPage")(function* (before, after, offset, limit, tail, sourceByteLimit, blobSize, readBlob) {
125
+ if (before !== null && !(before instanceof ResourceVersion))
126
+ return yield* failInput("before must be a ResourceVersion or None");
127
+ if (after !== null && !(after instanceof ResourceVersion))
128
+ return yield* failInput("after must be a ResourceVersion or None");
129
+ if (before !== null && after !== null && before.resourceId !== after.resourceId) {
130
+ return yield* failInput("resource versions must have the same resource ID");
131
+ }
132
+ const resource = after ?? before;
133
+ if (resource === null)
134
+ return yield* failInput("a resource diff requires before or after");
135
+ if (resourceVersionEqual(before, after)) {
136
+ return yield* failInput(`resource did not change between versions: ${resource.resourceId}`);
137
+ }
138
+ yield* validatePageArguments(resource.resourceId, offset, limit, tail);
139
+ if (sourceByteLimit !== null &&
140
+ sourceByteLimit !== undefined &&
141
+ (!Number.isInteger(sourceByteLimit) || sourceByteLimit <= 0))
142
+ return yield* failInput("source_byte_limit must be a positive integer or None");
143
+ const versions = [before, after].filter((version) => version !== null);
144
+ const unique = new Map();
145
+ for (const version of versions)
146
+ unique.set(version.blobId, version);
147
+ let actualBytes = 0;
148
+ for (const version of unique.values())
149
+ actualBytes += yield* blobSize(version.blobId);
150
+ if (sourceByteLimit !== null && sourceByteLimit !== undefined && actualBytes > sourceByteLimit) {
151
+ return yield* new RevisionContentLimitError({
152
+ actualBytes,
153
+ limitBytes: sourceByteLimit,
154
+ message: `resource diff source content exceeds ${sourceByteLimit} bytes`
155
+ });
156
+ }
157
+ const contents = new Map();
158
+ for (const version of unique.values())
159
+ contents.set(version.blobId, yield* readBlob(version.blobId));
160
+ const readExactBlob = (blobId) => {
161
+ const content = contents.get(blobId);
162
+ return content === undefined
163
+ ? Effect.fail(new CorruptRepositoryError({ message: `source blob is missing: ${blobId}` }))
164
+ : Effect.succeed(content);
165
+ };
166
+ return yield* diffPage(before, after, resource.resourceId, offset, limit, tail, readExactBlob);
167
+ });
168
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/domain/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AA6BtD,MAAM,SAAS,GAAG,CAAC,OAAe,EAAmD,EAAE,CACrF,MAAM,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;AAEzD,MAAM,oBAAoB,GAAG,CAC3B,IAA4B,EAC5B,KAA6B,EACpB,EAAE,CACX,IAAI,KAAK,KAAK;IACd,CAAC,IAAI,KAAK,IAAI;QACZ,KAAK,KAAK,IAAI;QACd,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;QACpC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;QACxB,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAC5B,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;QAC1B,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC,CAAA;AAEvC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;AAE5C,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,KAAa,EAAU,EAAE;IAC5D,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,GAAG,KAAK,GAAG,CAAC,IAAI,CAAA;IACxC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,GAAG,KAAK,EAAE,CAAA;IAClC,OAAO,GAAG,KAAK,IAAI,KAAK,EAAE,CAAA;AAC5B,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CACxB,MAAkB,EAClB,KAAiB,EACjB,QAAgB,EAChB,QAAgB,EACG,EAAE;IACrB,MAAM,KAAK,GAAG,eAAe,CAC3B,QAAQ,EACR,QAAQ,EACR,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAC1B,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EACzB,SAAS,EACT,SAAS,EACT,EAAE,OAAO,EAAE,CAAC,EAAE,CACf,CAAA;IACD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEvC,MAAM,MAAM,GAAa,CAAC,OAAO,QAAQ,IAAI,EAAE,OAAO,QAAQ,IAAI,CAAC,CAAA;IACnE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CACT,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CACxG,CAAA;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAClB,MAAkB,EAClB,KAAiB,EACjB,QAAgB,EAChB,QAAgB,EACR,EAAE,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAE1E,MAAM,UAAU,GAAG,CAAC,KAAa,EAAqB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAE1E,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,EAClD,MAAyB,EACzB,MAAc,EACd,KAAa,EACb,IAAa;IAEb,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1C,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAA;QAC5F,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,MAAM,CAAC,MAAM;YACxB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;SACxC,CAAA;IACH,CAAC;IACD,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAA;IAChE,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAA;IACzD,OAAO;QACL,MAAM;QACN,SAAS;QACT,OAAO,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM;QAClC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;KAC/C,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,qBAAqB,GAAG,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,QAAQ,CAAC,EACxE,UAAkB,EAClB,MAAc,EACd,KAAa,EACb,IAAa;IAEb,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAC3D,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAA;IAClE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QACzC,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAA;IACjE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QACxC,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAA;IAC7D,IAAI,OAAO,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAA;IAC7E,IAAI,IAAI,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAA;AACjG,CAAC,CAAC,CAAA;AAEF,MAAM,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,EAC5D,MAAkB,EAClB,KAAiB,EACjB,QAAgB,EAChB,QAAgB,EAChB,MAAc,EACd,KAAa,EACb,IAAa;IAEb,KAAK,CAAC,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IACzD,OAAO,KAAK,CAAC,CAAC,UAAU,CACtB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,EACpD,MAAM,EACN,KAAK,EACL,IAAI,CACL,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAC7C,MAAwB,EACxB,KAAuB,EACvB,WAAgD,EAChD,QAAoB;IAEpB,IAAI,QAAQ,GAA+B,IAAI,CAAA;IAC/C,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QACtD,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,YAAY,UAAU,EAAE,CAAC;YACzE,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,kDAAkD,CAAC,CAAA;QAC7E,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC,CAAA;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YAC3F,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,iDAAiD,CAAC,CAAA;QAC5E,CAAC;QACD,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5B,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACvE,MAAM,MAAM,GAAmB,EAAE,CAAA;IACjC,KAAK,MAAM,UAAU,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACjE,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,SAAQ;QAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAA;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAA;QAC1C,IAAI,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC;YAAE,SAAQ;QAC7C,MAAM,UAAU,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAChF,MAAM,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClF,MAAM,CAAC,IAAI,CAAC;YACV,UAAU;YACV,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,WAAW,CACtB,UAAU,EACV,UAAU,EACV,GAAG,EAAE,IAAI,IAAI,WAAW,EACxB,IAAI,EAAE,IAAI,IAAI,WAAW,CAC1B;SACF,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EACrD,MAA8B,EAC9B,KAA6B,EAC7B,UAAkB,EAClB,MAAc,EACd,KAAa,EACb,IAAa,EACb,QAAoB;IAEpB,KAAK,CAAC,CAAC,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7D,IAAI,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC;QACrC,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAA;IACrF,MAAM,UAAU,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACtF,MAAM,UAAU,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACpF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,eAAe,CACjC,UAAU,EACV,UAAU,EACV,MAAM,EAAE,IAAI,IAAI,WAAW,EAC3B,KAAK,EAAE,IAAI,IAAI,WAAW,EAC1B,MAAM,EACN,KAAK,EACL,IAAI,CACL,CAAA;IACD,OAAO;QACL,UAAU;QACV,MAAM;QACN,KAAK;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,CAAC,IAAI;KACvB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,EACrE,MAA8B,EAC9B,KAA6B,EAC7B,MAAc,EACd,KAAa,EACb,IAAa,EACb,eAA0C,EAC1C,QAAmB,EACnB,QAAoB;IAEpB,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,YAAY,eAAe,CAAC;QACzD,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAA;IACrE,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,YAAY,eAAe,CAAC;QACvD,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAA;IACpE,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC;QAChF,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,kDAAkD,CAAC,CAAA;IAC7E,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,IAAI,MAAM,CAAA;IAChC,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAA;IAC1F,IAAI,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,6CAA6C,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;IAC7F,CAAC;IACD,KAAK,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IACtE,IACE,eAAe,KAAK,IAAI;QACxB,eAAe,KAAK,SAAS;QAC7B,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,eAAe,IAAI,CAAC,CAAC;QAE5D,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,sDAAsD,CAAC,CAAA;IAEjF,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAA8B,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,CAAA;IAClG,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAA;IACjD,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnE,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,IAAI,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACrF,IAAI,eAAe,KAAK,IAAI,IAAI,eAAe,KAAK,SAAS,IAAI,WAAW,GAAG,eAAe,EAAE,CAAC;QAC/F,OAAO,KAAK,CAAC,CAAC,IAAI,yBAAyB,CAAC;YAC1C,WAAW;YACX,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE,wCAAwC,eAAe,QAAQ;SACzE,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAA;IAC9C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE;QACnC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/D,MAAM,aAAa,GAAe,CAAC,MAAM,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACpC,OAAO,OAAO,KAAK,SAAS;YAC1B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,sBAAsB,CAAC,EAAE,OAAO,EAAE,2BAA2B,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3F,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC,CAAA;IACD,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;AAChG,CAAC,CAAC,CAAA"}
@@ -0,0 +1,26 @@
1
+ import { Effect } from "effect";
2
+ import { CorruptRepositoryError } from "./errors.js";
3
+ import { type JsonRecord } from "./format.js";
4
+ interface TransactionRow {
5
+ readonly path: string;
6
+ readonly oldBlob: string | null;
7
+ readonly newBlob: string | null;
8
+ }
9
+ export interface Transaction {
10
+ readonly transactionId: string;
11
+ readonly oldHead: string | null;
12
+ readonly newHead: string;
13
+ readonly treeId: string;
14
+ readonly keyHash: string;
15
+ readonly requestHash: string;
16
+ readonly rows: readonly TransactionRow[];
17
+ }
18
+ export declare const transactionRecord: (transaction: Omit<Transaction, "transactionId">) => JsonRecord;
19
+ export declare const parseIdempotencyRecord: (content: Uint8Array<ArrayBufferLike>, keyHash: string) => Effect.Effect<{
20
+ readonly keyHash: string;
21
+ readonly requestHash: string;
22
+ readonly commitId: string;
23
+ }, CorruptRepositoryError, never>;
24
+ export declare const parseTransaction: (transactionId: string, content: Uint8Array<ArrayBufferLike>) => Effect.Effect<Transaction, CorruptRepositoryError, never>;
25
+ export {};
26
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/domain/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAIvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AA+B7C,UAAU,cAAc;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAA;CACzC;AAED,eAAO,MAAM,iBAAiB,gBAAiB,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,KAAG,UAalF,CAAA;AAEF,eAAO,MAAM,sBAAsB;sBAIb,MAAM;0BAAwB,MAAM;uBAAqB,MAAM;iCAmBnF,CAAA;AAEF,eAAO,MAAM,gBAAgB,4HAiD3B,CAAA"}
@@ -0,0 +1,93 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { decodeCanonicalJsonl } from "./codec.js";
3
+ import { normalizeRelativePath } from "./model.js";
4
+ import { CorruptRepositoryError } from "./errors.js";
5
+ import {} from "./format.js";
6
+ import { compareCodePoints } from "@arden-hq/std/json";
7
+ import { sha256Hex } from "@arden-hq/std/hash";
8
+ const Hash = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/));
9
+ const NonEmptyText = Schema.String.check(Schema.isMinLength(1));
10
+ const IdempotencyRecord = Schema.Struct({
11
+ commit_id: Hash,
12
+ key_hash: Hash,
13
+ request_hash: Hash,
14
+ version: Schema.Literal(2)
15
+ });
16
+ const TransactionRowRecord = Schema.Struct({
17
+ new_blob: Schema.NullOr(Hash),
18
+ old_blob: Schema.NullOr(Hash),
19
+ path: NonEmptyText
20
+ });
21
+ const TransactionRecord = Schema.Struct({
22
+ key_hash: Hash,
23
+ kind: Schema.Literal("transaction"),
24
+ new_head: Hash,
25
+ old_head: Schema.NullOr(Hash),
26
+ request_hash: Hash,
27
+ rows: Schema.Array(TransactionRowRecord),
28
+ tree_id: Hash,
29
+ version: Schema.Literal(2)
30
+ });
31
+ export const transactionRecord = (transaction) => ({
32
+ version: 2,
33
+ kind: "transaction",
34
+ old_head: transaction.oldHead,
35
+ new_head: transaction.newHead,
36
+ tree_id: transaction.treeId,
37
+ key_hash: transaction.keyHash,
38
+ request_hash: transaction.requestHash,
39
+ rows: transaction.rows.map((row) => ({
40
+ path: row.path,
41
+ old_blob: row.oldBlob,
42
+ new_blob: row.newBlob
43
+ }))
44
+ });
45
+ export const parseIdempotencyRecord = Effect.fn("Revision.parseIdempotencyRecord")(function* (content, keyHash) {
46
+ const record = yield* decodeCanonicalJsonl(content);
47
+ const decoded = yield* Schema.decodeUnknownEffect(IdempotencyRecord)(record, {
48
+ onExcessProperty: "error"
49
+ }).pipe(Effect.mapError(() => new CorruptRepositoryError({
50
+ message: `idempotency record ${keyHash} has an invalid shape`
51
+ })));
52
+ if (decoded.key_hash !== keyHash)
53
+ return yield* new CorruptRepositoryError({
54
+ message: `idempotency record ${keyHash} has the wrong key hash`
55
+ });
56
+ return { keyHash, requestHash: decoded.request_hash, commitId: decoded.commit_id };
57
+ });
58
+ export const parseTransaction = Effect.fn("Revision.parseTransaction")(function* (transactionId, content) {
59
+ if (sha256Hex(content) !== transactionId)
60
+ return yield* new CorruptRepositoryError({
61
+ message: `transaction ${transactionId} failed its manifest hash`
62
+ });
63
+ const record = yield* decodeCanonicalJsonl(content);
64
+ const decoded = yield* Schema.decodeUnknownEffect(TransactionRecord)(record, {
65
+ onExcessProperty: "error"
66
+ }).pipe(Effect.mapError(() => new CorruptRepositoryError({ message: `transaction ${transactionId} has an invalid shape` })));
67
+ const rows = [];
68
+ let previousPath;
69
+ for (const row of decoded.rows) {
70
+ const normalized = yield* normalizeRelativePath(row.path).pipe(Effect.mapError(() => new CorruptRepositoryError({ message: `transaction ${transactionId} has an unsafe path` })));
71
+ if (normalized !== row.path ||
72
+ (previousPath !== undefined && compareCodePoints(previousPath, row.path) >= 0))
73
+ return yield* new CorruptRepositoryError({
74
+ message: `transaction ${transactionId} rows are not uniquely ordered`
75
+ });
76
+ if (row.old_blob === row.new_blob)
77
+ return yield* new CorruptRepositoryError({
78
+ message: `transaction ${transactionId} row makes no change`
79
+ });
80
+ rows.push({ path: row.path, oldBlob: row.old_blob, newBlob: row.new_blob });
81
+ previousPath = row.path;
82
+ }
83
+ return {
84
+ transactionId,
85
+ oldHead: decoded.old_head,
86
+ newHead: decoded.new_head,
87
+ treeId: decoded.tree_id,
88
+ keyHash: decoded.key_hash,
89
+ requestHash: decoded.request_hash,
90
+ rows
91
+ };
92
+ });
93
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/domain/transaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Effect } from "effect";
2
+ import type { ResourceSnapshot } from "./change-set.js";
3
+ import { CorruptRepositoryError } from "./errors.js";
4
+ import { type TreeRecord } from "./format.js";
5
+ export declare const materializeSnapshot: <E>(readTree: (id: string) => Effect.Effect<TreeRecord, E>, treeId: string, cache?: Map<string, Effect.Effect<ResourceSnapshot, E | CorruptRepositoryError, never>> | undefined) => Effect.Effect<ResourceSnapshot, E | CorruptRepositoryError, never>;
6
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/domain/tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAO7C,eAAO,MAAM,mBAAmB,GAAwD,CAAC,iBACxE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,4LAwDtD,CAAA"}