@alchemy.run/pkg 2.0.0-beta.85 → 2.0.0-beta.87

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 (42) hide show
  1. package/README.md +4 -2
  2. package/dist/Manifest.d.ts.map +1 -1
  3. package/dist/Manifest.js.map +1 -1
  4. package/dist/Protocol.d.ts.map +1 -1
  5. package/dist/Protocol.js.map +1 -1
  6. package/dist/Registry/Bindings.d.ts +13 -0
  7. package/dist/Registry/Bindings.d.ts.map +1 -1
  8. package/dist/Registry/Bindings.js +6 -0
  9. package/dist/Registry/Bindings.js.map +1 -1
  10. package/dist/Registry/GitHub.d.ts +6 -8
  11. package/dist/Registry/GitHub.d.ts.map +1 -1
  12. package/dist/Registry/GitHub.js.map +1 -1
  13. package/dist/Registry/Handler.d.ts +7 -1
  14. package/dist/Registry/Handler.d.ts.map +1 -1
  15. package/dist/Registry/Handler.js +24 -1
  16. package/dist/Registry/Handler.js.map +1 -1
  17. package/dist/Registry/KVCache.d.ts.map +1 -1
  18. package/dist/Registry/KVCache.js.map +1 -1
  19. package/dist/Registry/Sweep.d.ts.map +1 -1
  20. package/dist/Registry/Sweep.js.map +1 -1
  21. package/dist/Registry/Tags.d.ts +24 -3
  22. package/dist/Registry/Tags.d.ts.map +1 -1
  23. package/dist/Registry/Tags.js +27 -6
  24. package/dist/Registry/Tags.js.map +1 -1
  25. package/dist/Registry.d.ts +33 -14
  26. package/dist/Registry.d.ts.map +1 -1
  27. package/dist/Registry.js +3 -0
  28. package/dist/Registry.js.map +1 -1
  29. package/dist/cli/bin.d.ts.map +1 -1
  30. package/dist/cli/bin.js.map +1 -1
  31. package/dist/cli/pack.d.ts.map +1 -1
  32. package/dist/cli/pack.js.map +1 -1
  33. package/dist/cli/publish.d.ts.map +1 -1
  34. package/dist/cli/publish.js.map +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js.map +1 -1
  37. package/migrations/0002_head_of.sql +6 -0
  38. package/package.json +10 -10
  39. package/src/Registry/Bindings.ts +6 -0
  40. package/src/Registry/Handler.ts +34 -1
  41. package/src/Registry/Tags.ts +34 -6
  42. package/src/Registry.ts +10 -0
@@ -18,6 +18,8 @@ export const TagRow = Schema.Struct({
18
18
  expires_at: Schema.Number,
19
19
  /** Pull requests whose runs produced this tag, as `owner/repo#N`. */
20
20
  linked_prs: LinkedPrs,
21
+ /** The kept branch this row is the latest publication of, if any. */
22
+ head_of: Schema.NullOr(Schema.String),
21
23
  });
22
24
  export type TagRow = typeof TagRow.Type;
23
25
 
@@ -39,8 +41,10 @@ export const get = Effect.fn("Tags.get")(function* (pkg: string, tag: string) {
39
41
 
40
42
  /**
41
43
  * Point `tag` at `sha256`, keeping the row alive for at least `expiresAt`
42
- * and remembering every pull request that produced it. One statement, so
43
- * concurrent publications of a shared tag merge rather than overwrite.
44
+ * and remembering every pull request that produced it. `headOf` marks the
45
+ * row as the latest publication of a kept branch; a publication without it
46
+ * leaves an existing mark alone. One statement, so concurrent publications
47
+ * of a shared tag merge rather than overwrite.
44
48
  */
45
49
  export const upsert = Effect.fn("Tags.upsert")(function* (input: {
46
50
  readonly package: string;
@@ -48,15 +52,17 @@ export const upsert = Effect.fn("Tags.upsert")(function* (input: {
48
52
  readonly sha256: string;
49
53
  readonly expiresAt: number;
50
54
  readonly prs: ReadonlyArray<string>;
55
+ readonly headOf: string | null;
51
56
  }) {
52
57
  const sql = yield* SqlClient.SqlClient;
53
58
  const prs = yield* Schema.encodeEffect(LinkedPrs)(input.prs);
54
59
  yield* sql`
55
- INSERT INTO tags (package, tag, sha256, expires_at, linked_prs)
56
- VALUES (${input.package}, ${input.tag}, ${input.sha256}, ${input.expiresAt}, ${prs})
60
+ INSERT INTO tags (package, tag, sha256, expires_at, linked_prs, head_of)
61
+ VALUES (${input.package}, ${input.tag}, ${input.sha256}, ${input.expiresAt}, ${prs}, ${input.headOf})
57
62
  ON CONFLICT (package, tag) DO UPDATE SET
58
63
  sha256 = excluded.sha256,
59
64
  expires_at = max(tags.expires_at, excluded.expires_at),
65
+ head_of = coalesce(excluded.head_of, tags.head_of),
60
66
  linked_prs = (
61
67
  SELECT json_group_array(value) FROM (
62
68
  SELECT value FROM json_each(tags.linked_prs)
@@ -91,12 +97,34 @@ export const setExpiry = Effect.fn("Tags.setExpiry")(function* (
91
97
  `;
92
98
  });
93
99
 
94
- /** Delete every expired row and return the tarballs those rows pointed at. */
100
+ /**
101
+ * Hand a kept branch's older rows of `pkg` back to the TTL once a newer
102
+ * publication from the branch has written `current`. Each released row
103
+ * lives until at least `expiresAt`.
104
+ */
105
+ export const releaseHead = Effect.fn("Tags.releaseHead")(function* (input: {
106
+ readonly package: string;
107
+ readonly branch: string;
108
+ readonly current: ReadonlyArray<string>;
109
+ readonly expiresAt: number;
110
+ }) {
111
+ const sql = yield* SqlClient.SqlClient;
112
+ yield* sql`
113
+ UPDATE tags SET head_of = NULL, expires_at = max(expires_at, ${input.expiresAt})
114
+ WHERE package = ${input.package} AND head_of = ${input.branch}
115
+ AND NOT ${sql.in("tag", input.current)}
116
+ `;
117
+ });
118
+
119
+ /**
120
+ * Delete every expired row and return the tarballs those rows pointed at.
121
+ * The latest publication of a kept branch never expires.
122
+ */
95
123
  export const deleteExpired = Effect.fn("Tags.deleteExpired")(function* (now: number) {
96
124
  const sql = yield* SqlClient.SqlClient;
97
125
  return yield* decodeTarballs(
98
126
  yield* sql`
99
- DELETE FROM tags WHERE expires_at < ${now} RETURNING package, sha256
127
+ DELETE FROM tags WHERE expires_at < ${now} AND head_of IS NULL RETURNING package, sha256
100
128
  `,
101
129
  );
102
130
  });
package/src/Registry.ts CHANGED
@@ -39,6 +39,13 @@ export interface RegistryOptions {
39
39
  readonly repos: ReadonlyArray<string>;
40
40
  /** @default Duration.weeks(1) */
41
41
  readonly ttl?: Duration.Duration;
42
+ /**
43
+ * Branches whose latest push publication never expires, such as
44
+ * `["main"]`. A newer push from the branch hands the previous
45
+ * publication back to the TTL, counted from that newer push.
46
+ * @default []
47
+ */
48
+ readonly keepLatest?: ReadonlyArray<string>;
42
49
  /** Upper bound on a single tarball. Absent means unlimited. */
43
50
  readonly maxPackageSize?: ByteSize.ByteSize;
44
51
  };
@@ -168,6 +175,9 @@ export const PkgRegistry = <const Id extends string>(id: Id, options: RegistryOp
168
175
  policy: {
169
176
  repos: options.policy.repos,
170
177
  ttl: options.policy.ttl ?? DEFAULT_TTL,
178
+ ...(options.policy.keepLatest !== undefined
179
+ ? { keepLatest: options.policy.keepLatest }
180
+ : {}),
171
181
  ...(options.policy.maxPackageSize !== undefined
172
182
  ? { maxPackageSize: options.policy.maxPackageSize }
173
183
  : {}),