@zhin.js/plugin-earthquake 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @zhin.js/plugin-earthquake
2
2
 
3
+ ## 0.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - a9f4e48: PATCH COMPATIBILITY CUTOVER: this batch intentionally changes plugin APIs. The maintainer explicitly chose patch releases with declared version boundaries. Upgrade the complete tested dependency set; patch numbering does not promise compatibility with the removed interfaces.
8
+
9
+ The first planned floors are zhin.js 1.1.19, Core 1.1.54, Adapter 1.1.26, FeatureKit 1.1.10, Plugin Runtime 1.1.18, Runtime/Isolate 1.1.16 and Agent 1.1.45. Keep old-interface plugins with the earlier locked stack until they are migrated. Adapter's independent Feature API changes from 1.0.0 to 2.0.0; official consumers declare ^2.0.0. Existing Feature API admission rejects explicitly incompatible ranges; omitted API metadata keeps its existing behavior and does not certify compatibility. Runtime engine and patch-only release gates remain unchanged.
10
+
11
+ Use the native-Client Adapter target contract, canonical FeatureKit AdapterRegistry augmentation and named Endpoint control/management requests. Route message controls from canonical message/conversation refs; retain exact source authority and propagate caller/account/explicit-Root-stop cancellation. Replace removed Agent activity feedback exports with source-bound feedback. HMR pause/resume belongs to concrete plugin instances; plugins choose accepted-work policy without changing Controller commit/rollback authority. Cooperative worker/process control cancellation does not kill an isolate or reopen retired business admission.
12
+
13
+ Provide authenticated historical-data preview, exact selected binding, transactional application, authoritative inspection and explicit resumption, including active games. Preserve before-images and journals; never replay an unconfirmed effect, infer an account from an alias, or reuse historical permission grants. Owner V2 approvals remain inactive legacy data, while new writes use V3. Rollback requires matching software, lockfile and verified data; installing old code alone cannot read a new V3 approval file. Conflicting after-images are never overwritten.
14
+
15
+ See docs/plans/adapter-operation-version-boundaries.md and the Chinese/English upgrade guide for the complete version inventory, custom-plugin changes, acceptance and recovery sequence. These code and metadata changes do not authorize merging, publication, deployment, login, production migration or removal of installed workspace patches.
16
+
17
+ - @zhin.js/skill@1.1.11
18
+ - @zhin.js/tool@1.1.13
19
+
20
+ ## 0.1.5
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies [c58c589]
25
+ - @zhin.js/tool@1.1.12
26
+
3
27
  ## 0.1.4
4
28
 
5
29
  ### Patch Changes
@@ -26,6 +26,7 @@ export default defineCommand({
26
26
  try {
27
27
  const { created } = await service.store.upsert({
28
28
  locale,
29
+ target: target.target,
29
30
  adapter: target.adapter,
30
31
  endpointKey: target.endpointKey,
31
32
  conversationKind: target.conversationKind,
@@ -1,6 +1,8 @@
1
+ import { type DeliveryTarget } from 'zhin.js/plugin-runtime';
1
2
  import type { Locale } from 'zhin.js/i18n';
2
3
  import type { ConversationKind } from './subscriptions.js';
3
4
  export interface ConversationTarget {
5
+ readonly target: DeliveryTarget;
4
6
  readonly adapter: string;
5
7
  readonly endpointKey: string;
6
8
  readonly conversationKind: ConversationKind;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAO3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,6BAA6B,uHAAwB,CAAC;AACnE,eAAO,MAAM,0BAA0B,+IAA4B,CAAC;AAYpE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAgB,GAAG,MAAM,CAGlF;AAED,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAuB7E"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAO3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,6BAA6B,uHAAwB,CAAC;AACnE,eAAO,MAAM,0BAA0B,+IAA4B,CAAC;AAYpE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAgB,GAAG,MAAM,CAGlF;AAED,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAwB7E"}
@@ -1,3 +1,4 @@
1
+ import { createDeliveryTarget } from 'zhin.js/plugin-runtime';
1
2
  import { messages as t } from './i18n.js';
2
3
  /**
3
4
  * Extracts a push destination from the public Message fields of a command input.
@@ -32,10 +33,10 @@ export function extractConversation(input) {
32
33
  const kind = conversation.kind;
33
34
  if (kind !== 'private' && kind !== 'group' && kind !== 'channel')
34
35
  return null;
35
- // Same precedence as core: explicit message fields, then the conversation's endpoint.
36
+ // Canonical scene identity is authoritative; display names are never persisted as account identity.
36
37
  const endpoint = isRecord(conversation.endpoint) ? conversation.endpoint : {};
37
- const adapter = isIdentifier(input.clientAdapter) ? input.clientAdapter : endpoint.adapter;
38
- const endpointKey = isIdentifier(input.endpointId) ? input.endpointId : endpoint.id;
38
+ const adapter = endpoint.adapter;
39
+ const endpointKey = endpoint.id;
39
40
  if (!isIdentifier(adapter))
40
41
  return null;
41
42
  if (!isIdentifier(endpointKey))
@@ -45,6 +46,7 @@ export function extractConversation(input) {
45
46
  const sender = input.sender;
46
47
  const senderId = isRecord(sender) && isIdentifier(sender.id) ? sender.id : '';
47
48
  return {
49
+ target: createDeliveryTarget({ conversation: conversation }),
48
50
  adapter,
49
51
  endpointKey,
50
52
  conversationKind: kind,
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,CAAC,EAAE,MAAM,WAAW,CAAC;AAC1C;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAWtD,MAAM,CAAC,MAAM,6BAA6B,GAAG,qBAAqB,CAAC;AACnE,MAAM,CAAC,MAAM,0BAA0B,GAAG,yBAAyB,CAAC;AAEpE,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,UAAU,CAAC,KAA8B;IAChD,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,YAAY,CAAC,MAAM,KAAK,SAAS,IAAI,YAAY,CAAC,QAAQ,KAAK,SAAS,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,SAAiB,OAAO;IACxE,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvE,OAAO,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AACnC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC9E,sFAAsF;IACtF,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;IAC3F,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;IACpF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,OAAO;QACL,OAAO;QACP,WAAW;QACX,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,YAAY,CAAC,EAAE;QAC/B,QAAQ;KACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAuB,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,QAAQ,IAAI,CAAC,EAAE,MAAM,WAAW,CAAC;AAC1C;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAYtD,MAAM,CAAC,MAAM,6BAA6B,GAAG,qBAAqB,CAAC;AACnE,MAAM,CAAC,MAAM,0BAA0B,GAAG,yBAAyB,CAAC;AAEpE,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,UAAU,CAAC,KAA8B;IAChD,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,YAAY,CAAC,MAAM,KAAK,SAAS,IAAI,YAAY,CAAC,QAAQ,KAAK,SAAS,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,SAAiB,OAAO;IACxE,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvE,OAAO,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AACnC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC9E,oGAAoG;IACpG,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;IAChC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,OAAO;QACL,MAAM,EAAE,oBAAoB,CAAC,EAAE,YAAY,EAAE,YAA8B,EAAE,CAAC;QAC9E,OAAO;QACP,WAAW;QACX,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,YAAY,CAAC,EAAE;QAC/B,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type JsonValue } from 'zhin.js/plugin-runtime';
2
+ export interface SubscriptionMigrationJournal {
3
+ readonly planDigest: string;
4
+ readonly candidateId: string;
5
+ readonly beforeDigest: string;
6
+ readonly afterDigest: string;
7
+ readonly recordCount: number;
8
+ readonly scopes: readonly string[];
9
+ readonly phase: 'pausing' | 'applied' | 'restoring' | 'restored' | 'rejected' | 'resumed';
10
+ readonly operation?: 'apply' | 'restore';
11
+ readonly rejectedDigest?: string;
12
+ }
13
+ export interface SubscriptionDocument {
14
+ readonly format: 'earthquake-subscriptions-v2';
15
+ readonly subscriptions: readonly JsonValue[];
16
+ readonly migrations: Readonly<Record<string, SubscriptionMigrationJournal>>;
17
+ }
18
+ export declare function subscriptionDocument(value: unknown): SubscriptionDocument;
19
+ //# sourceMappingURL=migration-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-document.d.ts","sourceRoot":"","sources":["../src/migration-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAE5E,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,SAAS,SAAS,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC,CAAC;CAC7E;AACD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAiBzE"}
@@ -0,0 +1,20 @@
1
+ import { DataMigrationError } from 'zhin.js/plugin-runtime';
2
+ export function subscriptionDocument(value) {
3
+ if (value === undefined)
4
+ return { format: 'earthquake-subscriptions-v2', subscriptions: [], migrations: {} };
5
+ if (Array.isArray(value))
6
+ return { format: 'earthquake-subscriptions-v2', subscriptions: value, migrations: {} };
7
+ if (value &&
8
+ typeof value === 'object' &&
9
+ 'format' in value &&
10
+ value.format === 'earthquake-subscriptions-v2' &&
11
+ 'subscriptions' in value &&
12
+ Array.isArray(value.subscriptions) &&
13
+ 'migrations' in value &&
14
+ value.migrations &&
15
+ typeof value.migrations === 'object' &&
16
+ !Array.isArray(value.migrations))
17
+ return value;
18
+ throw new DataMigrationError('unsupported', 'Earthquake subscriptions have an unrecognized storage format');
19
+ }
20
+ //# sourceMappingURL=migration-document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-document.js","sourceRoot":"","sources":["../src/migration-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAkB,MAAM,wBAAwB,CAAC;AAkB5E,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC7G,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACjH,IACE,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,QAAQ,IAAI,KAAK;QACjB,KAAK,CAAC,MAAM,KAAK,6BAA6B;QAC9C,eAAe,IAAI,KAAK;QACxB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;QAClC,YAAY,IAAI,KAAK;QACrB,KAAK,CAAC,UAAU;QAChB,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;QAEhC,OAAO,KAA6B,CAAC;IACvC,MAAM,IAAI,kBAAkB,CAAC,aAAa,EAAE,8DAA8D,CAAC,CAAC;AAC9G,CAAC"}
@@ -1,6 +1,9 @@
1
+ import { type DeliveryTarget, type JsonValue, type TargetMigrationScopes } from 'zhin.js/plugin-runtime';
1
2
  import { type Locale } from 'zhin.js/i18n';
2
3
  export type ConversationKind = 'private' | 'group' | 'channel';
3
4
  export interface EarthquakeSubscription {
5
+ /** Present on canonical captures; historical alias-only rows remain unchanged until migration is approved. */
6
+ readonly target?: DeliveryTarget;
4
7
  readonly locale?: Locale;
5
8
  readonly adapter: string;
6
9
  readonly endpointKey: string;
@@ -15,15 +18,17 @@ export interface EarthquakeSubscription {
15
18
  export interface KeyValueState {
16
19
  get(key: string): Promise<unknown>;
17
20
  set(key: string, value: never): Promise<void>;
21
+ update?<T extends JsonValue>(key: string, updater: (current: T | undefined) => T | undefined): Promise<T | undefined>;
18
22
  }
19
23
  export declare const SUBSCRIPTIONS_STATE_KEY = "subscriptions/v1";
20
- export declare function subscriptionKey(target: Pick<EarthquakeSubscription, 'adapter' | 'endpointKey' | 'conversationKind' | 'conversationId'>): string;
24
+ export declare function subscriptionKey(target: Pick<EarthquakeSubscription, 'adapter' | 'endpointKey' | 'conversationKind' | 'conversationId' | 'target'>): string;
21
25
  export declare function createMemoryState(): KeyValueState;
22
26
  export declare class SubscriptionStore {
23
27
  #private;
24
28
  constructor(state: KeyValueState, options: {
25
29
  readonly maxSubscriptions: number;
26
30
  });
31
+ bindMigrationScopes(scopes: TargetMigrationScopes): void;
27
32
  list(): Promise<EarthquakeSubscription[]>;
28
33
  get(key: string): Promise<EarthquakeSubscription | undefined>;
29
34
  /** Creates or replaces this conversation's subscription. */
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAW1D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,aAAa,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,MAAM,CAE/I;AA8BD,wBAAgB,iBAAiB,IAAI,aAAa,CAUjD;AAED,qBAAa,iBAAiB;;gBAKhB,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE;IAK1E,IAAI,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAWzC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;IAKnE,4DAA4D;IACtD,MAAM,CAAC,YAAY,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAkBpF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAoB5C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM;CAK1B"}
1
+ {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAClI,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAW1D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,8GAA8G;IAC9G,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CACvH;AAED,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,aAAa,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,QAAQ,CAAC,GAAG,MAAM,CAG1J;AA+BD,wBAAgB,iBAAiB,IAAI,aAAa,CAUjD;AAED,qBAAa,iBAAiB;;gBAMhB,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE;IAKhF,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAElD,IAAI,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAWzC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;IAKnE,4DAA4D;IACtD,MAAM,CAAC,YAAY,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAWpF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiC5C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM;CAK1B"}
@@ -1,3 +1,6 @@
1
+ import { conversationRefKey } from 'zhin.js';
2
+ import { subscriptionDocument } from './migration-document.js';
3
+ import { normalizeDeliveryTarget } from 'zhin.js/plugin-runtime';
1
4
  import { resolveLocale } from 'zhin.js/i18n';
2
5
  /**
3
6
  * Conversation subscriptions, one per conversation.
@@ -10,6 +13,8 @@ import { resolveLocale } from 'zhin.js/i18n';
10
13
  import { isRecord, toFiniteNumber, toTrimmedString } from './sources/parse-helpers.js';
11
14
  export const SUBSCRIPTIONS_STATE_KEY = 'subscriptions/v1';
12
15
  export function subscriptionKey(target) {
16
+ if (target.target)
17
+ return `canonical:${conversationRefKey(target.target)}`;
13
18
  return [target.adapter, target.endpointKey, target.conversationKind, target.conversationId].join('\u0000');
14
19
  }
15
20
  function isConversationKind(value) {
@@ -30,6 +35,7 @@ function parseStoredSubscription(value) {
30
35
  ? value.regions.filter((region) => typeof region === 'string' && region.trim() !== '')
31
36
  : [];
32
37
  return {
38
+ ...(value.target === undefined ? {} : { target: normalizeDeliveryTarget(value.target) }),
33
39
  adapter,
34
40
  locale: resolveLocale(value.locale),
35
41
  endpointKey,
@@ -56,14 +62,15 @@ export class SubscriptionStore {
56
62
  #state;
57
63
  #maxSubscriptions;
58
64
  #queue = Promise.resolve();
65
+ #migrationScopes;
59
66
  constructor(state, options) {
60
67
  this.#state = state;
61
68
  this.#maxSubscriptions = options.maxSubscriptions;
62
69
  }
70
+ bindMigrationScopes(scopes) { this.#migrationScopes = scopes; }
63
71
  async list() {
64
- const stored = await this.#state.get(SUBSCRIPTIONS_STATE_KEY);
65
- if (!Array.isArray(stored))
66
- return [];
72
+ const value = await this.#state.get(SUBSCRIPTIONS_STATE_KEY);
73
+ const stored = Array.isArray(value) ? value : subscriptionDocument(value).subscriptions;
67
74
  const subscriptions = [];
68
75
  for (const entry of stored) {
69
76
  const parsed = parseStoredSubscription(entry);
@@ -78,36 +85,43 @@ export class SubscriptionStore {
78
85
  }
79
86
  /** Creates or replaces this conversation's subscription. */
80
87
  async upsert(subscription) {
81
- return this.#serialize(async () => {
82
- const all = await this.list();
83
- const key = subscriptionKey(subscription);
84
- const index = all.findIndex((existing) => subscriptionKey(existing) === key);
85
- if (index === -1 && all.length >= this.#maxSubscriptions) {
88
+ const key = subscriptionKey(subscription);
89
+ return this.#run(key, () => this.#serialize(() => this.#mutate(all => {
90
+ const index = all.findIndex(existing => subscriptionKey(existing) === key);
91
+ if (index === -1 && all.length >= this.#maxSubscriptions)
86
92
  throw new SubscriptionLimitError(this.#maxSubscriptions);
87
- }
88
- if (index === -1) {
93
+ if (index === -1)
89
94
  all.push(subscription);
90
- }
91
- else {
95
+ else
92
96
  all[index] = { ...subscription, locale: resolveLocale(all[index]?.locale) };
93
- }
94
- await this.#write(all);
95
- return { created: index === -1 };
96
- });
97
+ return { subscriptions: all, result: { created: index === -1 } };
98
+ })));
97
99
  }
98
100
  async remove(key) {
99
- return this.#serialize(async () => {
100
- const all = await this.list();
101
- const remaining = all.filter((subscription) => subscriptionKey(subscription) !== key);
102
- if (remaining.length === all.length)
103
- return false;
104
- await this.#write(remaining);
105
- return true;
101
+ return this.#run(key, () => this.#serialize(() => this.#mutate(all => {
102
+ const subscriptions = all.filter(subscription => subscriptionKey(subscription) !== key);
103
+ return { subscriptions, result: subscriptions.length !== all.length };
104
+ })));
105
+ }
106
+ async #mutate(change) {
107
+ if (!this.#state.update) {
108
+ const changed = change(await this.list());
109
+ await this.#state.set(SUBSCRIPTIONS_STATE_KEY, changed.subscriptions);
110
+ return changed.result;
111
+ }
112
+ let result;
113
+ await this.#state.update(SUBSCRIPTIONS_STATE_KEY, current => {
114
+ const document = subscriptionDocument(current);
115
+ const all = document.subscriptions.flatMap(value => { const item = parseStoredSubscription(value); return item ? [item] : []; });
116
+ const changed = change(all);
117
+ result = changed.result;
118
+ const subscriptions = changed.subscriptions.map(subscription => ({ ...subscription, regions: [...subscription.regions] }));
119
+ return Array.isArray(current) || current === undefined ? subscriptions : { ...document, subscriptions };
106
120
  });
121
+ return result;
107
122
  }
108
- async #write(subscriptions) {
109
- const plain = subscriptions.map((subscription) => ({ ...subscription, regions: [...subscription.regions] }));
110
- await this.#state.set(SUBSCRIPTIONS_STATE_KEY, plain);
123
+ #run(scope, run) {
124
+ return this.#migrationScopes ? this.#migrationScopes.run({ scope, run }) : run();
111
125
  }
112
126
  #serialize(operation) {
113
127
  const next = this.#queue.then(operation, operation);
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { TargetMigrationScopes, type PluginDatabaseHost, type PluginDataMigrationProvider, type PluginStateStore } from 'zhin.js/plugin-runtime';
2
+ /** The selected subscription and its receipt commit in the same existing StateStore CAS. */
3
+ export declare function createEarthquakeTargetMigration(input: Readonly<{
4
+ database: PluginDatabaseHost;
5
+ state: PluginStateStore;
6
+ scopes: TargetMigrationScopes;
7
+ }>): PluginDataMigrationProvider;
8
+ //# sourceMappingURL=target-migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-migration.d.ts","sourceRoot":"","sources":["../src/target-migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,qBAAqB,EAOrB,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AA0EhC,4FAA4F;AAC5F,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,QAAQ,CAAC;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC,GACxG,2BAA2B,CAkV7B"}
@@ -0,0 +1,376 @@
1
+ import { generationAdmissionSource, DataMigrationError, normalizeDeliveryTarget, targetMigrationDigest, } from 'zhin.js/plugin-runtime';
2
+ import { SUBSCRIPTIONS_STATE_KEY, subscriptionKey } from './subscriptions.js';
3
+ import { subscriptionDocument, } from './migration-document.js';
4
+ function plain(value) {
5
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
6
+ }
7
+ function legacySelector(row) {
8
+ return {
9
+ adapter: row.adapter ?? null,
10
+ endpointKey: row.endpointKey ?? null,
11
+ conversationKind: row.conversationKind ?? null,
12
+ conversationId: row.conversationId ?? null,
13
+ target: row.target ?? null,
14
+ };
15
+ }
16
+ function units(document) {
17
+ const groups = new Map();
18
+ for (const [index, value] of document.subscriptions.entries()) {
19
+ const row = plain(value);
20
+ if (!row)
21
+ continue;
22
+ const selector = legacySelector(row), id = targetMigrationDigest(selector);
23
+ const group = groups.get(id) ?? {
24
+ indices: [],
25
+ rows: [],
26
+ selector,
27
+ };
28
+ group.indices.push(index);
29
+ group.rows.push(value);
30
+ groups.set(id, group);
31
+ }
32
+ return [...groups.entries()].map(([id, group]) => {
33
+ let status = Object.entries(group.selector).some(([key, value]) => key !== 'target' && (typeof value !== 'string' || !value))
34
+ ? 'corrupt'
35
+ : 'unresolved';
36
+ if (status !== 'corrupt' && group.selector.target !== null) {
37
+ try {
38
+ normalizeDeliveryTarget(group.selector.target);
39
+ status = 'canonical';
40
+ }
41
+ catch {
42
+ status = 'corrupt';
43
+ }
44
+ }
45
+ const first = group.rows[0];
46
+ return { ...group, id, status, scope: subscriptionKey(first), beforeDigest: targetMigrationDigest(group.rows) };
47
+ });
48
+ }
49
+ function receipt(plan, journal) {
50
+ if (!journal.operation)
51
+ return undefined;
52
+ return {
53
+ operation: journal.operation,
54
+ planId: plan.id,
55
+ candidateId: plan.candidateId,
56
+ beforeDigest: plan.beforeDigest,
57
+ afterDigest: journal.afterDigest,
58
+ recordCount: journal.recordCount,
59
+ status: 'applied',
60
+ maintenance: 'paused',
61
+ };
62
+ }
63
+ /** The selected subscription and its receipt commit in the same existing StateStore CAS. */
64
+ export function createEarthquakeTargetMigration(input) {
65
+ const { database, state, scopes } = input, inFlight = new Set();
66
+ let revision = 0;
67
+ const read = async () => subscriptionDocument(await state.get(SUBSCRIPTIONS_STATE_KEY));
68
+ const dataOf = (plan) => {
69
+ if (plan.domain !== 'earthquake' || plan.sourceVersion !== 'subscription-alias-v0')
70
+ throw new DataMigrationError('invalid_input', 'Plan belongs to another domain');
71
+ const data = plan.data;
72
+ if (!data || data.format !== 'earthquake-target-v2')
73
+ throw new DataMigrationError('invalid_input', 'Unsupported earthquake migration plan');
74
+ return data;
75
+ };
76
+ const update = async (change) => {
77
+ await state.update(SUBSCRIPTIONS_STATE_KEY, (current) => change(subscriptionDocument(current)));
78
+ };
79
+ scopes.bindInitialization(async () => {
80
+ for (const [planId, entry] of Object.entries((await read()).migrations))
81
+ if (entry.phase !== 'resumed')
82
+ scopes.restorePause(planId, entry.scopes);
83
+ });
84
+ const snapshots = (plan, document) => {
85
+ const data = dataOf(plan), all = units(document);
86
+ const source = all.find((unit) => unit.id === plan.candidateId);
87
+ const destinationId = targetMigrationDigest(legacySelector(plain(data.after[0])));
88
+ const destination = all.find((unit) => unit.id === destinationId);
89
+ return { source, destination, before: source?.rows ?? [], after: destination?.rows ?? [] };
90
+ };
91
+ const baseline = (plan, document) => {
92
+ const snapshot = snapshots(plan, document);
93
+ return targetMigrationDigest({ source: snapshot.before, destination: snapshot.after });
94
+ };
95
+ const rewrite = (rows, target) => rows.map((row) => ({
96
+ ...plain(row),
97
+ target,
98
+ adapter: target.endpoint.adapter,
99
+ endpointKey: target.endpoint.id,
100
+ conversationKind: target.kind,
101
+ conversationId: target.id,
102
+ }));
103
+ const inspect = (plan, document) => {
104
+ const data = dataOf(plan), entry = document.migrations[plan.id], snapshot = snapshots(plan, document);
105
+ const local = scopes.maintenance(plan.id, data.scopes);
106
+ const maintenance = local === 'unknown'
107
+ ? 'unknown'
108
+ : local === 'paused' || (entry && entry.phase !== 'resumed')
109
+ ? 'paused'
110
+ : 'resumed';
111
+ if (entry && entry.planDigest !== targetMigrationDigest(plan))
112
+ return { data: 'conflict', maintenance: 'unknown', resumable: false };
113
+ if (!scopes.drained(data.scopes))
114
+ return { data: 'unknown', maintenance, resumable: false };
115
+ if (entry?.rejectedDigest)
116
+ return {
117
+ data: baseline(plan, document) === entry.rejectedDigest && !entry.operation ? 'not_applied' : 'conflict',
118
+ maintenance,
119
+ resumable: maintenance === 'paused' && baseline(plan, document) === entry.rejectedDigest,
120
+ };
121
+ const confirmed = entry ? receipt(plan, entry) : undefined;
122
+ if (confirmed?.operation === 'apply' &&
123
+ snapshot.before.length === 0 &&
124
+ targetMigrationDigest(snapshot.after) === targetMigrationDigest(data.after))
125
+ return { data: 'applied', maintenance, receipt: confirmed, resumable: maintenance === 'paused' };
126
+ if (confirmed?.operation === 'restore' &&
127
+ snapshot.after.length === 0 &&
128
+ targetMigrationDigest(snapshot.before) === targetMigrationDigest(data.before))
129
+ return { data: 'restored', maintenance, receipt: confirmed, resumable: maintenance === 'paused' };
130
+ if (!confirmed &&
131
+ snapshot.after.length === 0 &&
132
+ targetMigrationDigest(snapshot.before) === targetMigrationDigest(data.before))
133
+ return { data: 'not_applied', maintenance, resumable: maintenance === 'paused' };
134
+ return { data: 'conflict', maintenance, resumable: false };
135
+ };
136
+ const mutate = async (plan, run) => {
137
+ if (inFlight.has(plan.id))
138
+ throw new DataMigrationError('conflict', 'Migration operation is already in progress');
139
+ revision += 1;
140
+ inFlight.add(plan.id);
141
+ try {
142
+ return await run();
143
+ }
144
+ finally {
145
+ inFlight.delete(plan.id);
146
+ }
147
+ };
148
+ const intent = (plan) => ({
149
+ planDigest: targetMigrationDigest(plan),
150
+ candidateId: plan.candidateId,
151
+ beforeDigest: plan.beforeDigest,
152
+ afterDigest: '',
153
+ recordCount: plan.recordCount,
154
+ scopes: dataOf(plan).scopes,
155
+ phase: 'pausing',
156
+ });
157
+ const rejected = async (plan, phase) => {
158
+ await update((document) => {
159
+ const entry = document.migrations[plan.id];
160
+ if (!entry || entry.planDigest !== targetMigrationDigest(plan) || entry.phase !== phase)
161
+ throw new DataMigrationError('commit_unknown', 'Cannot confirm rejected subscription migration');
162
+ return {
163
+ ...document,
164
+ migrations: {
165
+ ...document.migrations,
166
+ [plan.id]: { ...entry, phase: 'rejected', rejectedDigest: baseline(plan, document) },
167
+ },
168
+ };
169
+ });
170
+ };
171
+ return {
172
+ title: 'Earthquake subscription destinations',
173
+ get [generationAdmissionSource]() {
174
+ return database[generationAdmissionSource];
175
+ },
176
+ async preview(request) {
177
+ request?.signal?.throwIfAborted();
178
+ const document = await read();
179
+ const candidates = units(document).map((unit) => ({
180
+ id: unit.id,
181
+ domain: 'earthquake',
182
+ title: `Earthquake: ${String(unit.selector.conversationId)}`,
183
+ sourceVersion: 'subscription-alias-v0',
184
+ recordCount: unit.rows.length,
185
+ beforeDigest: unit.beforeDigest,
186
+ status: unit.status,
187
+ summary: unit.selector,
188
+ executable: unit.status === 'unresolved',
189
+ }));
190
+ return { revision: targetMigrationDigest(candidates), candidates };
191
+ },
192
+ async prepare(request) {
193
+ request.signal?.throwIfAborted();
194
+ const document = await read(), unit = units(document).find((value) => value.id === request.candidateId);
195
+ if (!unit)
196
+ throw new DataMigrationError('not_found', 'Historical earthquake subscription no longer exists');
197
+ if (unit.status !== 'unresolved')
198
+ throw new DataMigrationError('unsupported', 'Only unresolved historical subscriptions need binding');
199
+ if (unit.beforeDigest !== request.expectedDigest)
200
+ throw new DataMigrationError('conflict', 'Subscriptions changed since preview');
201
+ const target = normalizeDeliveryTarget(request.target), after = rewrite(unit.rows, target);
202
+ const destinationScope = subscriptionKey(after[0]);
203
+ if (document.subscriptions.some((row, index) => !unit.indices.includes(index) &&
204
+ subscriptionKey(row) === destinationScope))
205
+ throw new DataMigrationError('conflict', 'Selected destination already has an earthquake subscription');
206
+ return {
207
+ id: request.planId,
208
+ candidateId: unit.id,
209
+ domain: 'earthquake',
210
+ sourceVersion: 'subscription-alias-v0',
211
+ beforeDigest: unit.beforeDigest,
212
+ target,
213
+ recordCount: unit.rows.length,
214
+ data: { format: 'earthquake-target-v2', before: unit.rows, after, scopes: [unit.scope, destinationScope] },
215
+ description: [
216
+ 'Bind the selected subscriptions without changing filters, creation facts or any other subscription.',
217
+ 'The existing subscriptions document and migration journal share one CAS; remain paused until explicit resumption.',
218
+ ],
219
+ authorizationCandidates: [],
220
+ };
221
+ },
222
+ async inspect({ plan, signal }) {
223
+ signal?.throwIfAborted();
224
+ const started = revision;
225
+ if (inFlight.has(plan.id))
226
+ return { data: 'unknown', maintenance: 'unknown', resumable: false };
227
+ const result = inspect(plan, await read());
228
+ return revision === started && !inFlight.has(plan.id)
229
+ ? result
230
+ : { data: 'unknown', maintenance: 'unknown', resumable: false };
231
+ },
232
+ async apply({ plan, signal }) {
233
+ return mutate(plan, async () => {
234
+ const data = dataOf(plan);
235
+ signal?.throwIfAborted();
236
+ await scopes.pause({
237
+ planId: plan.id,
238
+ scopes: data.scopes,
239
+ persist: async () => update((document) => {
240
+ const entry = document.migrations[plan.id];
241
+ if (entry && entry.planDigest !== targetMigrationDigest(plan))
242
+ throw new DataMigrationError('conflict', 'Plan ID refers to another migration');
243
+ return entry
244
+ ? document
245
+ : { ...document, migrations: { ...document.migrations, [plan.id]: intent(plan) } };
246
+ }),
247
+ });
248
+ let callbackFailure;
249
+ try {
250
+ await update((document) => {
251
+ try {
252
+ signal?.throwIfAborted();
253
+ const entry = document.migrations[plan.id];
254
+ if (!entry || entry.phase !== 'pausing' || entry.planDigest !== targetMigrationDigest(plan))
255
+ throw new DataMigrationError('conflict', 'Migration is not waiting for application');
256
+ const snapshot = snapshots(plan, document);
257
+ if (snapshot.after.length ||
258
+ targetMigrationDigest(snapshot.before) !== targetMigrationDigest(data.before))
259
+ throw new DataMigrationError('conflict', 'Subscriptions changed before the atomic migration');
260
+ if (targetMigrationDigest(rewrite(snapshot.before, plan.target)) !== targetMigrationDigest(data.after))
261
+ throw new DataMigrationError('invalid_input', 'Plan changes more than subscription routing');
262
+ let position = 0;
263
+ const subscriptions = document.subscriptions.map((row, index) => snapshot.source.indices.includes(index) ? data.after[position++] : row);
264
+ return {
265
+ ...document,
266
+ subscriptions,
267
+ migrations: {
268
+ ...document.migrations,
269
+ [plan.id]: {
270
+ ...entry,
271
+ phase: 'applied',
272
+ operation: 'apply',
273
+ afterDigest: targetMigrationDigest(data.after),
274
+ },
275
+ },
276
+ };
277
+ }
278
+ catch (error) {
279
+ callbackFailure = error;
280
+ throw error;
281
+ }
282
+ });
283
+ }
284
+ catch (error) {
285
+ if (error === callbackFailure && error instanceof DataMigrationError)
286
+ await rejected(plan, 'pausing');
287
+ throw error;
288
+ }
289
+ const entry = (await read()).migrations[plan.id];
290
+ if (!entry?.operation)
291
+ throw new DataMigrationError('commit_unknown', 'Migration receipt cannot be confirmed');
292
+ return receipt(plan, entry);
293
+ });
294
+ },
295
+ async resume({ plan, signal }) {
296
+ return mutate(plan, async () => {
297
+ const data = dataOf(plan);
298
+ signal?.throwIfAborted();
299
+ await update((document) => {
300
+ const inspection = inspect(plan, document);
301
+ if (!inspection.resumable && inspection.maintenance !== 'resumed')
302
+ throw new DataMigrationError('conflict', 'Actual subscriptions do not permit resumption');
303
+ const entry = document.migrations[plan.id] ?? intent(plan);
304
+ return { ...document, migrations: { ...document.migrations, [plan.id]: { ...entry, phase: 'resumed' } } };
305
+ });
306
+ scopes.resume(plan.id, data.scopes);
307
+ });
308
+ },
309
+ async restore({ plan, receipt: original, signal }) {
310
+ return mutate(plan, async () => {
311
+ const data = dataOf(plan);
312
+ signal?.throwIfAborted();
313
+ await scopes.pause({
314
+ planId: plan.id,
315
+ scopes: data.scopes,
316
+ persist: async () => update((document) => {
317
+ const entry = document.migrations[plan.id];
318
+ if (!entry ||
319
+ entry.operation !== 'apply' ||
320
+ entry.afterDigest !== original.afterDigest ||
321
+ entry.planDigest !== targetMigrationDigest(plan))
322
+ throw new DataMigrationError('conflict', 'Restoration needs the matching committed receipt');
323
+ return {
324
+ ...document,
325
+ migrations: { ...document.migrations, [plan.id]: { ...entry, phase: 'restoring' } },
326
+ };
327
+ }),
328
+ });
329
+ let callbackFailure;
330
+ try {
331
+ await update((document) => {
332
+ try {
333
+ signal?.throwIfAborted();
334
+ const entry = document.migrations[plan.id];
335
+ const snapshot = snapshots(plan, document);
336
+ if (!entry ||
337
+ entry.phase !== 'restoring' ||
338
+ snapshot.before.length ||
339
+ targetMigrationDigest(snapshot.after) !== targetMigrationDigest(data.after))
340
+ throw new DataMigrationError('conflict', 'Subscriptions changed after migration; no records were overwritten');
341
+ let position = 0;
342
+ const subscriptions = document.subscriptions.map((row, index) => snapshot.destination.indices.includes(index) ? data.before[position++] : row);
343
+ return {
344
+ ...document,
345
+ subscriptions,
346
+ migrations: {
347
+ ...document.migrations,
348
+ [plan.id]: {
349
+ ...entry,
350
+ phase: 'restored',
351
+ operation: 'restore',
352
+ afterDigest: targetMigrationDigest(data.before),
353
+ },
354
+ },
355
+ };
356
+ }
357
+ catch (error) {
358
+ callbackFailure = error;
359
+ throw error;
360
+ }
361
+ });
362
+ }
363
+ catch (error) {
364
+ if (error === callbackFailure && error instanceof DataMigrationError)
365
+ await rejected(plan, 'restoring');
366
+ throw error;
367
+ }
368
+ const entry = (await read()).migrations[plan.id];
369
+ if (!entry?.operation)
370
+ throw new DataMigrationError('commit_unknown', 'Restoration receipt cannot be confirmed');
371
+ return receipt(plan, entry);
372
+ });
373
+ },
374
+ };
375
+ }
376
+ //# sourceMappingURL=target-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-migration.js","sourceRoot":"","sources":["../src/target-migration.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAElB,uBAAuB,EACvB,qBAAqB,GAQtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAA+B,MAAM,oBAAoB,CAAC;AAC3G,OAAO,EACL,oBAAoB,GAGrB,MAAM,yBAAyB,CAAC;AAQjC,SAAS,KAAK,CAAC,KAAgB;IAC7B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAmC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxH,CAAC;AACD,SAAS,cAAc,CAAC,GAA8B;IACpD,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;QAC5B,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;QACpC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,IAAI,IAAI;QAC9C,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,IAAI;QAC1C,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI;KAC3B,CAAC;AACJ,CAAC;AACD,SAAS,KAAK,CAAC,QAA8B;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyF,CAAC;IAChH,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9D,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,EAClC,EAAE,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,KAAK,GAAkF,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI;YAC7G,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE;YACR,QAAQ;SACT,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;QAC/C,IAAI,MAAM,GAA2C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CACtF,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,CAC5E;YACC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,YAAY,CAAC;QACjB,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC3D,IAAI,CAAC;gBACH,uBAAuB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC/C,MAAM,GAAG,WAAW,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAsC,CAAC;QACjE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IAClH,CAAC,CAAC,CAAC;AACL,CAAC;AACD,SAAS,OAAO,CAAC,IAAuB,EAAE,OAAqC;IAC7E,IAAI,CAAC,OAAO,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,QAAQ;KACtB,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,+BAA+B,CAC7C,KAAyG;IAEzG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EACvC,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC,oBAAoB,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,CAAC,IAAuB,EAAY,EAAE;QACnD,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,IAAI,IAAI,CAAC,aAAa,KAAK,uBAAuB;YAChF,MAAM,IAAI,kBAAkB,CAAC,eAAe,EAAE,gCAAgC,CAAC,CAAC;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,IAA2B,CAAC;QAC9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,sBAAsB;YACjD,MAAM,IAAI,kBAAkB,CAAC,eAAe,EAAE,uCAAuC,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAAE,MAAgE,EAAE,EAAE;QACxF,MAAM,KAAK,CAAC,MAAM,CAChB,uBAAuB,EACvB,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAyB,CAC3E,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE;QACnC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC;YACrE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,CAAC,IAAuB,EAAE,QAA8B,EAAE,EAAE;QAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EACvB,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC;QAChE,MAAM,aAAa,GAAG,qBAAqB,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAE,CAAC,CAAC,CAAC;QACpF,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;QAClE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;IAC7F,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,IAAuB,EAAE,QAA8B,EAAE,EAAE;QAC3E,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,OAAO,qBAAqB,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IACzF,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,IAA0B,EAAE,MAAmC,EAAwB,EAAE,CACxG,IAAI,CAAC,GAAG,CACN,CAAC,GAAG,EAAE,EAAE,CACN,CAAC;QACC,GAAG,KAAK,CAAC,GAAG,CAAE;QACd,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;QAChC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;QAC/B,gBAAgB,EAAE,MAAM,CAAC,IAAI;QAC7B,cAAc,EAAE,MAAM,CAAC,EAAE;KACD,CAAA,CAC7B,CAAC;IACJ,MAAM,OAAO,GAAG,CAAC,IAAuB,EAAE,QAA8B,EAA2B,EAAE;QACnG,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EACvB,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EACpC,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,WAAW,GACf,KAAK,KAAK,SAAS;YACjB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC;gBAC5D,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,KAAK,IAAI,KAAK,CAAC,UAAU,KAAK,qBAAqB,CAAC,IAAI,CAAC;YAC3D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACxE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QAC5F,IAAI,KAAK,EAAE,cAAc;YACvB,OAAO;gBACL,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU;gBACxG,WAAW;gBACX,SAAS,EAAE,WAAW,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC,cAAc;aACzF,CAAC;QACJ,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3D,IACE,SAAS,EAAE,SAAS,KAAK,OAAO;YAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAC5B,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;YAE3E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnG,IACE,SAAS,EAAE,SAAS,KAAK,SAAS;YAClC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAC3B,qBAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;YAE7E,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpG,IACE,CAAC,SAAS;YACV,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAC3B,qBAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;YAE7E,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnF,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC7D,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAAK,IAAuB,EAAE,GAAqB,EAAc,EAAE;QACrF,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,4CAA4C,CAAC,CAAC;QAClH,QAAQ,IAAI,CAAC,CAAC;QACd,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,EAAE,CAAC;QACrB,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,IAAuB,EAAgC,EAAE,CAAC,CAAC;QACzE,UAAU,EAAE,qBAAqB,CAAC,IAAI,CAAC;QACvC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;QAC3B,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,KAAK,EAAE,IAAuB,EAAE,KAA4C,EAAE,EAAE;QAC/F,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;YACxB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,KAAK,qBAAqB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;gBACrF,MAAM,IAAI,kBAAkB,CAAC,gBAAgB,EAAE,gDAAgD,CAAC,CAAC;YACnG,OAAO;gBACL,GAAG,QAAQ;gBACX,UAAU,EAAE;oBACV,GAAG,QAAQ,CAAC,UAAU;oBACtB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;iBACrF;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO;QACL,KAAK,EAAE,sCAAsC;QAC7C,IAAI,CAAC,yBAAyB,CAAC;YAC7B,OAAO,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChD,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,MAAM,EAAE,YAAY;gBACpB,KAAK,EAAE,eAAe,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;gBAC5D,aAAa,EAAE,uBAAuB;gBACtC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;gBAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,OAAO,EAAE,IAAI,CAAC,QAAQ;gBACtB,UAAU,EAAE,IAAI,CAAC,MAAM,KAAK,YAAY;aACzC,CAAC,CAAC,CAAC;YACJ,OAAO,EAAE,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;QACrE,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,EAC3B,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;YAC3E,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,kBAAkB,CAAC,WAAW,EAAE,qDAAqD,CAAC,CAAC;YAC5G,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY;gBAC9B,MAAM,IAAI,kBAAkB,CAAC,aAAa,EAAE,uDAAuD,CAAC,CAAC;YACvG,IAAI,IAAI,CAAC,YAAY,KAAK,OAAO,CAAC,cAAc;gBAC9C,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,qCAAqC,CAAC,CAAC;YAClF,MAAM,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC,EACpD,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACrC,MAAM,gBAAgB,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAsC,CAAC,CAAC;YACxF,IACE,QAAQ,CAAC,aAAa,CAAC,IAAI,CACzB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CACb,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAC7B,eAAe,CAAC,GAAwC,CAAC,KAAK,gBAAgB,CACjF;gBAED,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,6DAA6D,CAAC,CAAC;YAC1G,OAAO;gBACL,EAAE,EAAE,OAAO,CAAC,MAAM;gBAClB,WAAW,EAAE,IAAI,CAAC,EAAE;gBACpB,MAAM,EAAE,YAAY;gBACpB,aAAa,EAAE,uBAAuB;gBACtC,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,MAAM;gBACN,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;gBAC7B,IAAI,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAE;gBAC1G,WAAW,EAAE;oBACX,qGAAqG;oBACrG,mHAAmH;iBACpH;gBACD,uBAAuB,EAAE,EAAE;aAC5B,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;YAC5B,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,QAAQ,CAAC;YACzB,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAChG,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;YAC3C,OAAO,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnD,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACpE,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;YAC1B,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;gBACzB,MAAM,MAAM,CAAC,KAAK,CAAC;oBACjB,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,KAAK,IAAI,EAAE,CAClB,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;wBAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBAC3C,IAAI,KAAK,IAAI,KAAK,CAAC,UAAU,KAAK,qBAAqB,CAAC,IAAI,CAAC;4BAC3D,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,qCAAqC,CAAC,CAAC;wBAClF,OAAO,KAAK;4BACV,CAAC,CAAC,QAAQ;4BACV,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,EAAE,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;oBACvF,CAAC,CAAC;iBACL,CAAC,CAAC;gBACH,IAAI,eAAwB,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;wBACxB,IAAI,CAAC;4BACH,MAAM,EAAE,cAAc,EAAE,CAAC;4BACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;4BAC3C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,qBAAqB,CAAC,IAAI,CAAC;gCACzF,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,0CAA0C,CAAC,CAAC;4BACvF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;4BAC3C,IACE,QAAQ,CAAC,KAAK,CAAC,MAAM;gCACrB,qBAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;gCAE7E,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,mDAAmD,CAAC,CAAC;4BAChG,IAAI,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;gCACpG,MAAM,IAAI,kBAAkB,CAAC,eAAe,EAAE,6CAA6C,CAAC,CAAC;4BAC/F,IAAI,QAAQ,GAAG,CAAC,CAAC;4BACjB,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC9D,QAAQ,CAAC,MAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAE,CAAC,CAAC,CAAC,GAAG,CACzE,CAAC;4BACF,OAAO;gCACL,GAAG,QAAQ;gCACX,aAAa;gCACb,UAAU,EAAE;oCACV,GAAG,QAAQ,CAAC,UAAU;oCACtB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;wCACT,GAAG,KAAK;wCACR,KAAK,EAAE,SAAS;wCAChB,SAAS,EAAE,OAAO;wCAClB,WAAW,EAAE,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;qCAC/C;iCACF;6BACF,CAAC;wBACJ,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,eAAe,GAAG,KAAK,CAAC;4BACxB,MAAM,KAAK,CAAC;wBACd,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,KAAK,eAAe,IAAI,KAAK,YAAY,kBAAkB;wBAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBACtG,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,KAAK,EAAE,SAAS;oBAAE,MAAM,IAAI,kBAAkB,CAAC,gBAAgB,EAAE,uCAAuC,CAAC,CAAC;gBAC/G,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,CAAE,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;YAC3B,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;gBACzB,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;oBACxB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;oBAC3C,IAAI,CAAC,UAAU,CAAC,SAAS,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS;wBAC/D,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,+CAA+C,CAAC,CAAC;oBAC5F,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC3D,OAAO,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,EAAE,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;gBAC5G,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;YAC/C,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;gBACzB,MAAM,MAAM,CAAC,KAAK,CAAC;oBACjB,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,KAAK,IAAI,EAAE,CAClB,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;wBAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBAC3C,IACE,CAAC,KAAK;4BACN,KAAK,CAAC,SAAS,KAAK,OAAO;4BAC3B,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW;4BAC1C,KAAK,CAAC,UAAU,KAAK,qBAAqB,CAAC,IAAI,CAAC;4BAEhD,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,kDAAkD,CAAC,CAAC;wBAC/F,OAAO;4BACL,GAAG,QAAQ;4BACX,UAAU,EAAE,EAAE,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;yBACpF,CAAC;oBACJ,CAAC,CAAC;iBACL,CAAC,CAAC;gBACH,IAAI,eAAwB,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;wBACxB,IAAI,CAAC;4BACH,MAAM,EAAE,cAAc,EAAE,CAAC;4BACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;4BAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;4BAC3C,IACE,CAAC,KAAK;gCACN,KAAK,CAAC,KAAK,KAAK,WAAW;gCAC3B,QAAQ,CAAC,MAAM,CAAC,MAAM;gCACtB,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;gCAE3E,MAAM,IAAI,kBAAkB,CAC1B,UAAU,EACV,oEAAoE,CACrE,CAAC;4BACJ,IAAI,QAAQ,GAAG,CAAC,CAAC;4BACjB,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC9D,QAAQ,CAAC,WAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAE,CAAC,CAAC,CAAC,GAAG,CAC/E,CAAC;4BACF,OAAO;gCACL,GAAG,QAAQ;gCACX,aAAa;gCACb,UAAU,EAAE;oCACV,GAAG,QAAQ,CAAC,UAAU;oCACtB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;wCACT,GAAG,KAAK;wCACR,KAAK,EAAE,UAAU;wCACjB,SAAS,EAAE,SAAS;wCACpB,WAAW,EAAE,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;qCAChD;iCACF;6BACF,CAAC;wBACJ,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,eAAe,GAAG,KAAK,CAAC;4BACxB,MAAM,KAAK,CAAC;wBACd,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,KAAK,eAAe,IAAI,KAAK,YAAY,kBAAkB;wBAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACxG,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,KAAK,EAAE,SAAS;oBACnB,MAAM,IAAI,kBAAkB,CAAC,gBAAgB,EAAE,yCAAyC,CAAC,CAAC;gBAC5F,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,CAAE,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-earthquake",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Earthquake query and group alert plugin for Zhin.js — CENC + USGS, magnitude/region subscriptions (Plugin Runtime)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -41,21 +41,21 @@
41
41
  },
42
42
  "license": "MIT",
43
43
  "dependencies": {
44
- "@zhin.js/skill": "1.1.10",
45
- "@zhin.js/tool": "1.1.11"
44
+ "@zhin.js/skill": "1.1.11",
45
+ "@zhin.js/tool": "1.1.13"
46
46
  },
47
47
  "devDependencies": {
48
48
  "typescript": "^6.0.3",
49
49
  "vitest": "^4.1.10",
50
50
  "zod": "^4.4.3",
51
- "@zhin.js/command": "1.1.11",
52
- "@zhin.js/testing": "1.0.6",
53
- "zhin.js": "1.1.17"
51
+ "@zhin.js/command": "1.1.12",
52
+ "@zhin.js/testing": "1.0.7",
53
+ "zhin.js": "1.1.19"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "zod": "^4.0.0",
57
- "@zhin.js/command": "^1.1.11",
58
- "zhin.js": "^1.1.17"
57
+ "@zhin.js/command": "^1.1.12",
58
+ "zhin.js": "^1.1.19"
59
59
  },
60
60
  "peerDependenciesMeta": {
61
61
  "@zhin.js/command": {
package/plugin.js CHANGED
@@ -1,10 +1,12 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { DataMigrationError, pluginDataMigrationProviderToken, TargetMigrationScopes } from 'zhin.js/plugin-runtime';
3
+ import { createEarthquakeTargetMigration } from "./lib/target-migration.js";
2
4
  import { resolveLocale } from 'zhin.js/i18n';
3
5
  import { databaseHostToken, definePlugin, logger, outboundHostToken, scheduleHostToken, } from 'zhin.js';
4
6
  import { assertEarthquakeTimezone, resolveEarthquakeConfig, } from "./lib/config.js";
5
7
  import { earthquakeServiceToken } from "./lib/runtime.js";
6
8
  import { EarthquakeService } from "./lib/service.js";
7
- import { createMemoryState, SubscriptionStore } from "./lib/subscriptions.js";
9
+ import { createMemoryState, SubscriptionStore, subscriptionKey } from "./lib/subscriptions.js";
8
10
  /**
9
11
  * Plugin Runtime:
10
12
  * - Commands: `地震` query, `地震 订阅` / `地震 退订` / `地震 订阅状态`.
@@ -21,9 +23,12 @@ export default definePlugin({
21
23
  const config = resolveEarthquakeConfig(context.config.get());
22
24
  assertEarthquakeTimezone(config.timezone);
23
25
  let state;
24
- if (context.resources.has(databaseHostToken)) {
26
+ let durableState;
27
+ const database = context.resources.has(databaseHostToken) ? context.resources.use(databaseHostToken) : undefined;
28
+ if (database) {
25
29
  try {
26
- state = context.resources.use(databaseHostToken).state;
30
+ durableState = database.state;
31
+ state = durableState;
27
32
  }
28
33
  catch {
29
34
  // No persistent state port: fall back to memory below.
@@ -32,20 +37,27 @@ export default definePlugin({
32
37
  const store = new SubscriptionStore(state ?? createMemoryState(), {
33
38
  maxSubscriptions: config.maxSubscriptions,
34
39
  });
40
+ const migrationScopes = database && durableState ? new TargetMigrationScopes({ pending: scope => !scope.startsWith('canonical:') }) : undefined;
41
+ if (database && durableState && migrationScopes) {
42
+ store.bindMigrationScopes(migrationScopes);
43
+ context.resources.provide(pluginDataMigrationProviderToken, createEarthquakeTargetMigration({ database,
44
+ state: durableState, scopes: migrationScopes }));
45
+ }
35
46
  let push;
36
47
  if (context.resources.has(outboundHostToken)) {
37
48
  const outbound = context.resources.use(outboundHostToken);
38
49
  push = async (subscription, content) => {
39
- await outbound.send({
40
- adapter: subscription.adapter,
41
- endpointKey: subscription.endpointKey,
42
- conversation: {
43
- kind: subscription.conversationKind,
44
- id: subscription.conversationId,
45
- },
46
- content,
47
- locale: resolveLocale(subscription.locale),
48
- });
50
+ const target = subscription.target;
51
+ if (!target)
52
+ throw new DataMigrationError('unavailable', 'Historical earthquake subscription awaits exact-target binding');
53
+ const send = outbound.sendTarget;
54
+ if (!send)
55
+ throw new Error('Canonical subscription delivery requires an exact-target Outbound Host');
56
+ const run = async () => { await send(target, content, { locale: resolveLocale(subscription.locale) }); };
57
+ if (migrationScopes)
58
+ await migrationScopes.run({ scope: subscriptionKey(subscription), run });
59
+ else
60
+ await run();
49
61
  };
50
62
  }
51
63
  const service = new EarthquakeService({