@se-studio/contentful-cms 2.6.0 → 2.7.0

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 (104) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/audit/asset-usage.d.ts +14 -0
  3. package/dist/audit/asset-usage.d.ts.map +1 -1
  4. package/dist/audit/asset-usage.js +18 -0
  5. package/dist/audit/asset-usage.js.map +1 -1
  6. package/dist/audit/media-review.d.ts +4 -0
  7. package/dist/audit/media-review.d.ts.map +1 -1
  8. package/dist/audit/media-review.js.map +1 -1
  9. package/dist/commands/asset.d.ts.map +1 -1
  10. package/dist/commands/asset.js +19 -9
  11. package/dist/commands/asset.js.map +1 -1
  12. package/dist/commands/create-from-json.d.ts.map +1 -1
  13. package/dist/commands/create-from-json.js +11 -0
  14. package/dist/commands/create-from-json.js.map +1 -1
  15. package/dist/commands/create-taxonomy.d.ts.map +1 -1
  16. package/dist/commands/create-taxonomy.js +5 -3
  17. package/dist/commands/create-taxonomy.js.map +1 -1
  18. package/dist/commands/create.d.ts.map +1 -1
  19. package/dist/commands/create.js +13 -3
  20. package/dist/commands/create.js.map +1 -1
  21. package/dist/commands/nav.d.ts.map +1 -1
  22. package/dist/commands/nav.js +14 -0
  23. package/dist/commands/nav.js.map +1 -1
  24. package/dist/commands/save.d.ts.map +1 -1
  25. package/dist/commands/save.js +13 -0
  26. package/dist/commands/save.js.map +1 -1
  27. package/dist/generated/hosted-guide.d.ts +1 -1
  28. package/dist/generated/hosted-guide.d.ts.map +1 -1
  29. package/dist/generated/hosted-guide.js +1 -1
  30. package/dist/generated/hosted-guide.js.map +1 -1
  31. package/dist/generated/version.d.ts +1 -1
  32. package/dist/generated/version.js +1 -1
  33. package/dist/hosted/index.d.ts +1 -0
  34. package/dist/hosted/index.d.ts.map +1 -1
  35. package/dist/hosted/index.js +1 -0
  36. package/dist/hosted/index.js.map +1 -1
  37. package/dist/hosted/next/redis.d.ts.map +1 -1
  38. package/dist/hosted/next/redis.js +11 -3
  39. package/dist/hosted/next/redis.js.map +1 -1
  40. package/dist/hosted/next/routes/mcp.d.ts.map +1 -1
  41. package/dist/hosted/next/routes/mcp.js +2 -1
  42. package/dist/hosted/next/routes/mcp.js.map +1 -1
  43. package/dist/index/blob.d.ts +5 -0
  44. package/dist/index/blob.d.ts.map +1 -0
  45. package/dist/index/blob.js +15 -0
  46. package/dist/index/blob.js.map +1 -0
  47. package/dist/index/cache-keys.d.ts +9 -0
  48. package/dist/index/cache-keys.d.ts.map +1 -0
  49. package/dist/index/cache-keys.js +13 -0
  50. package/dist/index/cache-keys.js.map +1 -0
  51. package/dist/index/cache-store.d.ts +31 -0
  52. package/dist/index/cache-store.d.ts.map +1 -0
  53. package/dist/index/cache-store.js +17 -0
  54. package/dist/index/cache-store.js.map +1 -0
  55. package/dist/index/distributed-sync-lock.d.ts +3 -0
  56. package/dist/index/distributed-sync-lock.d.ts.map +1 -0
  57. package/dist/index/distributed-sync-lock.js +22 -0
  58. package/dist/index/distributed-sync-lock.js.map +1 -0
  59. package/dist/index/file-index-cache.d.ts +16 -0
  60. package/dist/index/file-index-cache.d.ts.map +1 -0
  61. package/dist/index/file-index-cache.js +103 -0
  62. package/dist/index/file-index-cache.js.map +1 -0
  63. package/dist/index/hydrate.d.ts +4 -0
  64. package/dist/index/hydrate.d.ts.map +1 -0
  65. package/dist/index/hydrate.js +24 -0
  66. package/dist/index/hydrate.js.map +1 -0
  67. package/dist/index/invalidate.d.ts +24 -0
  68. package/dist/index/invalidate.d.ts.map +1 -0
  69. package/dist/index/invalidate.js +60 -0
  70. package/dist/index/invalidate.js.map +1 -0
  71. package/dist/index/patch-index.d.ts +12 -0
  72. package/dist/index/patch-index.d.ts.map +1 -0
  73. package/dist/index/patch-index.js +40 -0
  74. package/dist/index/patch-index.js.map +1 -0
  75. package/dist/index/publish-cache.d.ts +5 -0
  76. package/dist/index/publish-cache.d.ts.map +1 -0
  77. package/dist/index/publish-cache.js +26 -0
  78. package/dist/index/publish-cache.js.map +1 -0
  79. package/dist/index/redis-index-cache.d.ts +24 -0
  80. package/dist/index/redis-index-cache.d.ts.map +1 -0
  81. package/dist/index/redis-index-cache.js +83 -0
  82. package/dist/index/redis-index-cache.js.map +1 -0
  83. package/dist/index/require.d.ts +5 -4
  84. package/dist/index/require.d.ts.map +1 -1
  85. package/dist/index/require.js +17 -6
  86. package/dist/index/require.js.map +1 -1
  87. package/dist/index/run-sync.d.ts +2 -0
  88. package/dist/index/run-sync.d.ts.map +1 -1
  89. package/dist/index/run-sync.js +16 -9
  90. package/dist/index/run-sync.js.map +1 -1
  91. package/dist/index/sync.d.ts +9 -1
  92. package/dist/index/sync.d.ts.map +1 -1
  93. package/dist/index/sync.js +53 -0
  94. package/dist/index/sync.js.map +1 -1
  95. package/dist/runtime/context.d.ts +3 -0
  96. package/dist/runtime/context.d.ts.map +1 -1
  97. package/dist/runtime/context.js.map +1 -1
  98. package/dist/session/session-store.d.ts +2 -1
  99. package/dist/session/session-store.d.ts.map +1 -1
  100. package/docs/help/asset-review.md +4 -2
  101. package/docs/help/index-sync.md +9 -3
  102. package/docs/mcp/e2e-test-prompt.md +159 -0
  103. package/docs/mcp/hosted-guide.md +6 -0
  104. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../../src/index/blob.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEnD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAErD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE1D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAEvE"}
@@ -0,0 +1,15 @@
1
+ import * as fs from 'node:fs';
2
+ import * as zlib from 'node:zlib';
3
+ export function gzipBuffer(data) {
4
+ return zlib.gzipSync(data);
5
+ }
6
+ export function gunzipBuffer(data) {
7
+ return zlib.gunzipSync(data);
8
+ }
9
+ export function readFileBytes(filePath) {
10
+ return fs.readFileSync(filePath);
11
+ }
12
+ export function writeFileBytes(filePath, data) {
13
+ fs.writeFileSync(filePath, data);
14
+ }
15
+ //# sourceMappingURL=blob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob.js","sourceRoot":"","sources":["../../src/index/blob.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC3C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAgB;IAC/D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { SpaceConfig } from '../config/types.js';
2
+ export interface IndexCacheKey {
3
+ spaceId: string;
4
+ environment: string;
5
+ preview: boolean;
6
+ }
7
+ export declare function indexCacheKeyFromSpace(space: SpaceConfig, preview?: boolean): IndexCacheKey;
8
+ export declare function indexCacheKeySuffix(key: IndexCacheKey): string;
9
+ //# sourceMappingURL=cache-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-keys.d.ts","sourceRoot":"","sources":["../../src/index/cache-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,CAM3F;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAG9D"}
@@ -0,0 +1,13 @@
1
+ import { resolveIndexPreview } from './mode.js';
2
+ export function indexCacheKeyFromSpace(space, preview) {
3
+ return {
4
+ spaceId: space.spaceId,
5
+ environment: space.environment,
6
+ preview: resolveIndexPreview(preview),
7
+ };
8
+ }
9
+ export function indexCacheKeySuffix(key) {
10
+ const mode = key.preview ? 'preview' : 'published';
11
+ return `${key.spaceId}:${key.environment}:${mode}`;
12
+ }
13
+ //# sourceMappingURL=cache-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-keys.js","sourceRoot":"","sources":["../../src/index/cache-keys.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAQhD,MAAM,UAAU,sBAAsB,CAAC,KAAkB,EAAE,OAAiB;IAC1E,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,mBAAmB,CAAC,OAAO,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAkB;IACpD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;IACnD,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { IndexCacheKey } from './cache-keys.js';
2
+ export type IndexInvalidationMode = 'incremental' | 'full';
3
+ export interface IndexInvalidation {
4
+ invalidatedAt: string;
5
+ mode: IndexInvalidationMode;
6
+ }
7
+ export interface IndexBlobMeta {
8
+ syncedAt: string;
9
+ schemaVersion: number;
10
+ assetCount: number;
11
+ referenceCount: number;
12
+ }
13
+ export interface IndexCacheStore {
14
+ getInvalidation(key: IndexCacheKey): Promise<IndexInvalidation | null>;
15
+ setInvalidation(key: IndexCacheKey, inv: IndexInvalidation): Promise<void>;
16
+ clearInvalidation(key: IndexCacheKey): Promise<void>;
17
+ getBlob(key: IndexCacheKey): Promise<{
18
+ meta: IndexBlobMeta;
19
+ data: Uint8Array;
20
+ } | null>;
21
+ putBlob(key: IndexCacheKey, meta: IndexBlobMeta, data: Uint8Array): Promise<void>;
22
+ deleteBlob(key: IndexCacheKey): Promise<void>;
23
+ tryAcquireSyncLock(key: IndexCacheKey, holderId: string, ttlSeconds: number): Promise<boolean>;
24
+ releaseSyncLock(key: IndexCacheKey, holderId: string): Promise<void>;
25
+ }
26
+ declare const INDEX_BLOB_TTL_SECONDS: number;
27
+ export { INDEX_BLOB_TTL_SECONDS };
28
+ export declare function getIndexCacheStore(): IndexCacheStore;
29
+ /** @internal Reset singleton between tests. */
30
+ export declare function resetDefaultIndexCacheStoreForTests(): void;
31
+ //# sourceMappingURL=cache-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-store.d.ts","sourceRoot":"","sources":["../../src/index/cache-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,MAAM,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACvE,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/F,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAED,QAAA,MAAM,sBAAsB,QAAmB,CAAC;AAEhD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAIlC,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD;AAED,+CAA+C;AAC/C,wBAAgB,mCAAmC,IAAI,IAAI,CAE1D"}
@@ -0,0 +1,17 @@
1
+ import { getRuntimeContext } from '../runtime/context.js';
2
+ import { FileIndexCacheStore } from './file-index-cache.js';
3
+ const INDEX_BLOB_TTL_SECONDS = 60 * 60 * 24 * 7;
4
+ export { INDEX_BLOB_TTL_SECONDS };
5
+ let defaultFileStore;
6
+ export function getIndexCacheStore() {
7
+ const fromContext = getRuntimeContext()?.indexCacheStore;
8
+ if (fromContext)
9
+ return fromContext;
10
+ defaultFileStore ??= new FileIndexCacheStore();
11
+ return defaultFileStore;
12
+ }
13
+ /** @internal Reset singleton between tests. */
14
+ export function resetDefaultIndexCacheStoreForTests() {
15
+ defaultFileStore = undefined;
16
+ }
17
+ //# sourceMappingURL=cache-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-store.js","sourceRoot":"","sources":["../../src/index/cache-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AA2B5D,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAEhD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC,IAAI,gBAAiD,CAAC;AAEtD,MAAM,UAAU,kBAAkB;IAChC,MAAM,WAAW,GAAG,iBAAiB,EAAE,EAAE,eAAe,CAAC;IACzD,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,gBAAgB,KAAK,IAAI,mBAAmB,EAAE,CAAC;IAC/C,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,mCAAmC;IACjD,gBAAgB,GAAG,SAAS,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SpaceConfig } from '../config/types.js';
2
+ export declare function withDistributedIndexSyncLock<T>(space: SpaceConfig, preview: boolean | undefined, dbPath: string, fn: () => Promise<T>): Promise<T>;
3
+ //# sourceMappingURL=distributed-sync-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distributed-sync-lock.d.ts","sourceRoot":"","sources":["../../src/index/distributed-sync-lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQtD,wBAAsB,4BAA4B,CAAC,CAAC,EAClD,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAkBZ"}
@@ -0,0 +1,22 @@
1
+ import { indexCacheKeyFromSpace } from './cache-keys.js';
2
+ import { getIndexCacheStore } from './cache-store.js';
3
+ import { resolveIndexPreview } from './mode.js';
4
+ import { IndexSyncLockError, withIndexSyncLock } from './sync-lock.js';
5
+ const DISTRIBUTED_SYNC_LOCK_TTL_SECONDS = 300;
6
+ export async function withDistributedIndexSyncLock(space, preview, dbPath, fn) {
7
+ const usePreview = resolveIndexPreview(preview);
8
+ const cache = getIndexCacheStore();
9
+ const key = indexCacheKeyFromSpace(space, usePreview);
10
+ const holderId = `${String(process.pid)}-${Date.now().toString()}`;
11
+ const acquired = await cache.tryAcquireSyncLock(key, holderId, DISTRIBUTED_SYNC_LOCK_TTL_SECONDS);
12
+ if (!acquired) {
13
+ throw new IndexSyncLockError('Another index sync is in progress for this space (shared lock). Retry shortly.');
14
+ }
15
+ try {
16
+ return await withIndexSyncLock(dbPath, fn);
17
+ }
18
+ finally {
19
+ await cache.releaseSyncLock(key, holderId);
20
+ }
21
+ }
22
+ //# sourceMappingURL=distributed-sync-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distributed-sync-lock.js","sourceRoot":"","sources":["../../src/index/distributed-sync-lock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,iCAAiC,GAAG,GAAG,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,KAAkB,EAClB,OAA4B,EAC5B,MAAc,EACd,EAAoB;IAEpB,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,sBAAsB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IAEnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,iCAAiC,CAAC,CAAC;IAClG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,kBAAkB,CAC1B,gFAAgF,CACjF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,MAAM,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { IndexCacheKey } from './cache-keys.js';
2
+ import type { IndexBlobMeta, IndexCacheStore, IndexInvalidation } from './cache-store.js';
3
+ export declare class FileIndexCacheStore implements IndexCacheStore {
4
+ getInvalidation(key: IndexCacheKey): Promise<IndexInvalidation | null>;
5
+ setInvalidation(key: IndexCacheKey, inv: IndexInvalidation): Promise<void>;
6
+ clearInvalidation(key: IndexCacheKey): Promise<void>;
7
+ getBlob(key: IndexCacheKey): Promise<{
8
+ meta: IndexBlobMeta;
9
+ data: Uint8Array;
10
+ } | null>;
11
+ putBlob(key: IndexCacheKey, meta: IndexBlobMeta, data: Uint8Array): Promise<void>;
12
+ deleteBlob(key: IndexCacheKey): Promise<void>;
13
+ tryAcquireSyncLock(key: IndexCacheKey, holderId: string, ttlSeconds: number): Promise<boolean>;
14
+ releaseSyncLock(key: IndexCacheKey, holderId: string): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=file-index-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-index-cache.d.ts","sourceRoot":"","sources":["../../src/index/file-index-cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA0C1F,qBAAa,mBAAoB,YAAW,eAAe;IACnD,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAItE,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAWtF,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjF,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7C,kBAAkB,CACtB,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IAWb,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAW3E"}
@@ -0,0 +1,103 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { getIndexDirectory } from './paths.js';
4
+ function cacheDirForKey(key) {
5
+ const space = {
6
+ spaceId: key.spaceId,
7
+ environment: key.environment,
8
+ managementToken: '',
9
+ defaultLocale: 'en-US',
10
+ };
11
+ return getIndexDirectory(space, key.preview);
12
+ }
13
+ function invalidationPath(key) {
14
+ return path.join(cacheDirForKey(key), 'invalidation.json');
15
+ }
16
+ function blobPath(key) {
17
+ return path.join(cacheDirForKey(key), 'media.db.gz');
18
+ }
19
+ function blobMetaPath(key) {
20
+ return path.join(cacheDirForKey(key), 'index-blob-meta.json');
21
+ }
22
+ function lockPath(key) {
23
+ return path.join(cacheDirForKey(key), 'sync.lock');
24
+ }
25
+ function readJsonFile(filePath) {
26
+ try {
27
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ function writeJsonFile(filePath, value) {
34
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
35
+ fs.writeFileSync(filePath, `${JSON.stringify(value)}\n`, 'utf8');
36
+ }
37
+ export class FileIndexCacheStore {
38
+ async getInvalidation(key) {
39
+ return readJsonFile(invalidationPath(key));
40
+ }
41
+ async setInvalidation(key, inv) {
42
+ writeJsonFile(invalidationPath(key), inv);
43
+ }
44
+ async clearInvalidation(key) {
45
+ try {
46
+ fs.unlinkSync(invalidationPath(key));
47
+ }
48
+ catch {
49
+ // missing is fine
50
+ }
51
+ }
52
+ async getBlob(key) {
53
+ const meta = readJsonFile(blobMetaPath(key));
54
+ if (!meta)
55
+ return null;
56
+ try {
57
+ const data = fs.readFileSync(blobPath(key));
58
+ return { meta, data };
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ async putBlob(key, meta, data) {
65
+ const dir = cacheDirForKey(key);
66
+ fs.mkdirSync(dir, { recursive: true });
67
+ fs.writeFileSync(blobPath(key), data);
68
+ writeJsonFile(blobMetaPath(key), meta);
69
+ }
70
+ async deleteBlob(key) {
71
+ for (const file of [blobPath(key), blobMetaPath(key)]) {
72
+ try {
73
+ fs.unlinkSync(file);
74
+ }
75
+ catch {
76
+ // missing is fine
77
+ }
78
+ }
79
+ }
80
+ async tryAcquireSyncLock(key, holderId, ttlSeconds) {
81
+ const lockFile = lockPath(key);
82
+ const now = Date.now();
83
+ const existing = readJsonFile(lockFile);
84
+ if (existing && existing.expiresAt > now && existing.holderId !== holderId) {
85
+ return false;
86
+ }
87
+ writeJsonFile(lockFile, { holderId, expiresAt: now + ttlSeconds * 1000 });
88
+ return true;
89
+ }
90
+ async releaseSyncLock(key, holderId) {
91
+ const lockFile = lockPath(key);
92
+ const existing = readJsonFile(lockFile);
93
+ if (existing?.holderId === holderId) {
94
+ try {
95
+ fs.unlinkSync(lockFile);
96
+ }
97
+ catch {
98
+ // missing is fine
99
+ }
100
+ }
101
+ }
102
+ }
103
+ //# sourceMappingURL=file-index-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-index-cache.js","sourceRoot":"","sources":["../../src/index/file-index-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { SpaceConfig } from '../config/types.js';
2
+ /** Restores a local SQLite index from a shared cache blob when missing and not invalidated. */
3
+ export declare function tryHydrateIndexFromCache(space: SpaceConfig, preview?: boolean): Promise<boolean>;
4
+ //# sourceMappingURL=hydrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../src/index/hydrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOtD,+FAA+F;AAC/F,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
@@ -0,0 +1,24 @@
1
+ import { gunzipBuffer, writeFileBytes } from './blob.js';
2
+ import { indexCacheKeyFromSpace } from './cache-keys.js';
3
+ import { getIndexCacheStore } from './cache-store.js';
4
+ import { resolveIndexPreview } from './mode.js';
5
+ import { ensureIndexDirectory, getIndexDbPath, indexExists } from './paths.js';
6
+ /** Restores a local SQLite index from a shared cache blob when missing and not invalidated. */
7
+ export async function tryHydrateIndexFromCache(space, preview) {
8
+ const usePreview = resolveIndexPreview(preview);
9
+ if (indexExists(space, usePreview))
10
+ return false;
11
+ const cache = getIndexCacheStore();
12
+ const key = indexCacheKeyFromSpace(space, usePreview);
13
+ const [inv, blob] = await Promise.all([cache.getInvalidation(key), cache.getBlob(key)]);
14
+ if (!blob)
15
+ return false;
16
+ if (inv && Date.parse(inv.invalidatedAt) > Date.parse(blob.meta.syncedAt)) {
17
+ return false;
18
+ }
19
+ ensureIndexDirectory(space, usePreview);
20
+ const dbPath = getIndexDbPath(space, usePreview);
21
+ writeFileBytes(dbPath, gunzipBuffer(blob.data));
22
+ return true;
23
+ }
24
+ //# sourceMappingURL=hydrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate.js","sourceRoot":"","sources":["../../src/index/hydrate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/E,+FAA+F;AAC/F,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAkB,EAClB,OAAiB;IAEjB,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAEjD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,sBAAsB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACtD,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxF,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAExB,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,cAAc,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { EntryProps } from 'contentful-management';
2
+ import type { SpaceConfig } from '../config/types.js';
3
+ import type { CdaAssetRecord } from '../contentful/cda-sync.js';
4
+ import type { SerializedEntry } from '../session/state.js';
5
+ import { type IndexInvalidationMode } from './cache-store.js';
6
+ import type { CatalogContentType } from './schema.js';
7
+ export interface NotifyContentIndexChangedOptions {
8
+ mode?: IndexInvalidationMode;
9
+ session?: {
10
+ defaultLocale: string;
11
+ entries: Record<string, SerializedEntry>;
12
+ originalEntries: Record<string, SerializedEntry>;
13
+ };
14
+ savedEntryIds?: string[];
15
+ deletedEntryIds?: string[];
16
+ createdEntries?: Array<{
17
+ contentType: CatalogContentType;
18
+ entry: EntryProps;
19
+ }>;
20
+ upsertAssets?: CdaAssetRecord[];
21
+ }
22
+ /** Marks the shared index dirty and patches the local SQLite copy when present. Does not sync. */
23
+ export declare function notifyContentIndexChanged(space: SpaceConfig, opts?: NotifyContentIndexChangedOptions): Promise<void>;
24
+ //# sourceMappingURL=invalidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalidate.d.ts","sourceRoot":"","sources":["../../src/index/invalidate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAMlF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,WAAW,gCAAgC;IAC/C,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,OAAO,CAAC,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QACzC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;KAClD,CAAC;IACF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,kBAAkB,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IAC/E,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;CACjC;AAoCD,kGAAkG;AAClG,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,WAAW,EAClB,IAAI,GAAE,gCAAqC,GAC1C,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
@@ -0,0 +1,60 @@
1
+ import { indexCacheKeyFromSpace } from './cache-keys.js';
2
+ import { getIndexCacheStore } from './cache-store.js';
3
+ import { patchIndexFromAssets, patchIndexFromCreatedEntries, patchIndexFromSavedEntries, } from './patch-index.js';
4
+ import { isCatalogContentType } from './schema.js';
5
+ function pickSlug(entry, locale) {
6
+ const slugField = entry.fields['slug'];
7
+ if (!slugField)
8
+ return null;
9
+ const raw = slugField[locale] ?? slugField['en-US'];
10
+ return raw != null ? String(raw) : null;
11
+ }
12
+ function resolveInvalidationMode(opts) {
13
+ if (opts.mode)
14
+ return opts.mode;
15
+ const deleted = opts.deletedEntryIds ?? [];
16
+ const session = opts.session;
17
+ if (session) {
18
+ for (const id of deleted) {
19
+ const entry = session.entries[id];
20
+ if (entry && isCatalogContentType(entry.sys.contentType.sys.id)) {
21
+ return 'full';
22
+ }
23
+ }
24
+ for (const id of opts.savedEntryIds ?? []) {
25
+ const entry = session.entries[id];
26
+ const original = session.originalEntries[id];
27
+ if (!entry || !original)
28
+ continue;
29
+ if (!isCatalogContentType(entry.sys.contentType.sys.id))
30
+ continue;
31
+ if (pickSlug(entry, session.defaultLocale) !== pickSlug(original, session.defaultLocale)) {
32
+ return 'full';
33
+ }
34
+ }
35
+ }
36
+ return 'incremental';
37
+ }
38
+ /** Marks the shared index dirty and patches the local SQLite copy when present. Does not sync. */
39
+ export async function notifyContentIndexChanged(space, opts = {}) {
40
+ const mode = resolveInvalidationMode(opts);
41
+ const cache = getIndexCacheStore();
42
+ const key = indexCacheKeyFromSpace(space);
43
+ await cache.setInvalidation(key, {
44
+ invalidatedAt: new Date().toISOString(),
45
+ mode,
46
+ });
47
+ if (mode === 'full') {
48
+ await cache.deleteBlob(key);
49
+ }
50
+ if (opts.session) {
51
+ patchIndexFromSavedEntries(space, opts.session.defaultLocale, opts.savedEntryIds ?? [], opts.deletedEntryIds ?? [], opts.session.entries);
52
+ }
53
+ if (opts.createdEntries?.length) {
54
+ patchIndexFromCreatedEntries(space, space.defaultLocale, opts.createdEntries);
55
+ }
56
+ if (opts.upsertAssets?.length) {
57
+ patchIndexFromAssets(space, opts.upsertAssets);
58
+ }
59
+ }
60
+ //# sourceMappingURL=invalidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalidate.js","sourceRoot":"","sources":["../../src/index/invalidate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { EntryProps } from 'contentful-management';
2
+ import type { SpaceConfig } from '../config/types.js';
3
+ import type { CdaAssetRecord } from '../contentful/cda-sync.js';
4
+ import type { SerializedEntry } from '../session/state.js';
5
+ import type { CatalogContentType } from './schema.js';
6
+ export declare function patchIndexFromSavedEntries(space: SpaceConfig, locale: string, savedEntryIds: string[], deletedEntryIds: string[], entries: Record<string, SerializedEntry>): void;
7
+ export declare function patchIndexFromCreatedEntries(space: SpaceConfig, locale: string, created: Array<{
8
+ contentType: CatalogContentType;
9
+ entry: EntryProps;
10
+ }>): void;
11
+ export declare function patchIndexFromAssets(space: SpaceConfig, assets: CdaAssetRecord[]): void;
12
+ //# sourceMappingURL=patch-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch-index.d.ts","sourceRoot":"","sources":["../../src/index/patch-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AActD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EAAE,EACvB,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GACvC,IAAI,CAoBN;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,KAAK,CAAC;IAAE,WAAW,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC,GACrE,IAAI,CAIN;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAIvF"}
@@ -0,0 +1,40 @@
1
+ import { referenceRowFromCmaEntry } from '../contentful/reference-record.js';
2
+ import { isCatalogContentType } from './schema.js';
3
+ import { deleteReferenceRow, upsertAssetRow, upsertReferenceRow } from './sync.js';
4
+ function entryLikeFromSerialized(entry) {
5
+ return {
6
+ sys: { id: entry.sys.id, updatedAt: entry.sys.updatedAt },
7
+ fields: entry.fields,
8
+ };
9
+ }
10
+ export function patchIndexFromSavedEntries(space, locale, savedEntryIds, deletedEntryIds, entries) {
11
+ for (const id of deletedEntryIds) {
12
+ const entry = entries[id];
13
+ if (!entry)
14
+ continue;
15
+ const contentType = entry.sys.contentType.sys.id;
16
+ if (isCatalogContentType(contentType)) {
17
+ deleteReferenceRow(space, id);
18
+ }
19
+ }
20
+ for (const id of savedEntryIds) {
21
+ const entry = entries[id];
22
+ if (!entry)
23
+ continue;
24
+ const contentType = entry.sys.contentType.sys.id;
25
+ if (!isCatalogContentType(contentType))
26
+ continue;
27
+ upsertReferenceRow(space, referenceRowFromCmaEntry(contentType, entryLikeFromSerialized(entry), locale));
28
+ }
29
+ }
30
+ export function patchIndexFromCreatedEntries(space, locale, created) {
31
+ for (const { contentType, entry } of created) {
32
+ upsertReferenceRow(space, referenceRowFromCmaEntry(contentType, entry, locale));
33
+ }
34
+ }
35
+ export function patchIndexFromAssets(space, assets) {
36
+ for (const asset of assets) {
37
+ upsertAssetRow(space, asset);
38
+ }
39
+ }
40
+ //# sourceMappingURL=patch-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch-index.js","sourceRoot":"","sources":["../../src/index/patch-index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAG7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEnF,SAAS,uBAAuB,CAAC,KAAsB;IAIrD,OAAO;QACL,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE;QACzD,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAAkB,EAClB,MAAc,EACd,aAAuB,EACvB,eAAyB,EACzB,OAAwC;IAExC,KAAK,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,IAAI,oBAAoB,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,kBAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC;YAAE,SAAS;QACjD,kBAAkB,CAChB,KAAK,EACL,wBAAwB,CAAC,WAAW,EAAE,uBAAuB,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAC9E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAkB,EAClB,MAAc,EACd,OAAsE;IAEtE,KAAK,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC;QAC7C,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAkB,EAAE,MAAwB;IAC/E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { SpaceConfig } from '../config/types.js';
2
+ import type { SyncIndexResult } from './sync.js';
3
+ /** Uploads the local SQLite index to the shared cache after a successful sync. */
4
+ export declare function publishIndexCache(space: SpaceConfig, preview: boolean | undefined, result: SyncIndexResult): Promise<void>;
5
+ //# sourceMappingURL=publish-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-cache.d.ts","sourceRoot":"","sources":["../../src/index/publish-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,kFAAkF;AAClF,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
@@ -0,0 +1,26 @@
1
+ import { gzipBuffer, readFileBytes } from './blob.js';
2
+ import { indexCacheKeyFromSpace } from './cache-keys.js';
3
+ import { getIndexCacheStore } from './cache-store.js';
4
+ import { resolveIndexPreview } from './mode.js';
5
+ import { getIndexDbPath } from './paths.js';
6
+ import { SCHEMA_VERSION } from './schema.js';
7
+ /** Uploads the local SQLite index to the shared cache after a successful sync. */
8
+ export async function publishIndexCache(space, preview, result) {
9
+ const usePreview = resolveIndexPreview(preview);
10
+ const cache = getIndexCacheStore();
11
+ const key = indexCacheKeyFromSpace(space, usePreview);
12
+ const dbPath = getIndexDbPath(space, usePreview);
13
+ const raw = readFileBytes(dbPath);
14
+ const gz = gzipBuffer(raw);
15
+ await cache.putBlob(key, {
16
+ syncedAt: result.syncedAt,
17
+ schemaVersion: SCHEMA_VERSION,
18
+ assetCount: result.assetCount,
19
+ referenceCount: result.referenceCount,
20
+ }, gz);
21
+ const inv = await cache.getInvalidation(key);
22
+ if (inv && Date.parse(inv.invalidatedAt) <= Date.parse(result.syncedAt)) {
23
+ await cache.clearInvalidation(key);
24
+ }
25
+ }
26
+ //# sourceMappingURL=publish-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-cache.js","sourceRoot":"","sources":["../../src/index/publish-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAkB,EAClB,OAA4B,EAC5B,MAAuB;IAEvB,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,sBAAsB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAE3B,MAAM,KAAK,CAAC,OAAO,CACjB,GAAG,EACH;QACE,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,cAAc;QAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxE,MAAM,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { RedisClient } from '../session/session-store.js';
2
+ import type { IndexCacheKey } from './cache-keys.js';
3
+ import { type IndexBlobMeta, type IndexCacheStore, type IndexInvalidation } from './cache-store.js';
4
+ export declare class RedisIndexCacheStore implements IndexCacheStore {
5
+ private readonly redis;
6
+ private readonly blobTtlSeconds;
7
+ constructor(redis: RedisClient, blobTtlSeconds?: number);
8
+ private invalidationKey;
9
+ private blobMetaKey;
10
+ private blobDataKey;
11
+ private syncLockKey;
12
+ getInvalidation(key: IndexCacheKey): Promise<IndexInvalidation | null>;
13
+ setInvalidation(key: IndexCacheKey, inv: IndexInvalidation): Promise<void>;
14
+ clearInvalidation(key: IndexCacheKey): Promise<void>;
15
+ getBlob(key: IndexCacheKey): Promise<{
16
+ meta: IndexBlobMeta;
17
+ data: Uint8Array;
18
+ } | null>;
19
+ putBlob(key: IndexCacheKey, meta: IndexBlobMeta, data: Uint8Array): Promise<void>;
20
+ deleteBlob(key: IndexCacheKey): Promise<void>;
21
+ tryAcquireSyncLock(key: IndexCacheKey, holderId: string, ttlSeconds: number): Promise<boolean>;
22
+ releaseSyncLock(key: IndexCacheKey, holderId: string): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=redis-index-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-index-cache.d.ts","sourceRoot":"","sources":["../../src/index/redis-index-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAmB1B,qBAAa,oBAAqB,YAAW,eAAe;IAExD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBADd,KAAK,EAAE,WAAW,EAClB,cAAc,SAAyB;IAG1D,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAIb,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAItE,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAStF,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,kBAAkB,CACtB,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IAQb,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAM3E"}