@wtfalch/foundry 0.16.16 → 0.17.1
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/dist/apply.d.ts +22 -1
- package/dist/bootstrap/bootstrap.d.ts +6 -1
- package/dist/bootstrap/bootstrap.js +26 -3
- package/dist/bootstrap/declare.d.ts +11 -1
- package/dist/bootstrap/declare.js +18 -6
- package/dist/index.d.ts +11 -6
- package/dist/index.js +8 -1
- package/dist/migrations/0038_calls_version_pin.sql +8 -0
- package/dist/migrations/0039_destroy_record.sql +7 -0
- package/dist/migrations/0040_company_included_uuid.sql +72 -0
- package/dist/migrations/0041_company_included_uuid_keys.sql +132 -0
- package/dist/migrations/0042_mutation_leases.sql +12 -0
- package/dist/migrations/0043_platform_names.sql +25 -0
- package/dist/migrations/0044_platform_mail_lettermint_project.sql +11 -0
- package/dist/org.d.ts +128 -3
- package/dist/org.js +186 -1
- package/dist/plan/adopt.d.ts +76 -0
- package/dist/plan/adopt.js +184 -0
- package/dist/plan/agora.d.ts +21 -0
- package/dist/plan/agora.js +37 -0
- package/dist/plan/broker-entries.d.ts +9 -1
- package/dist/plan/broker-entries.js +13 -5
- package/dist/plan/chat-matrix.d.ts +1 -2
- package/dist/plan/chat-matrix.js +15 -4
- package/dist/plan/core-files.d.ts +25 -0
- package/dist/plan/core-files.js +25 -0
- package/dist/plan/diff.d.ts +27 -3
- package/dist/plan/diff.js +264 -86
- package/dist/plan/edge-worker.d.ts +114 -0
- package/dist/plan/edge-worker.js +201 -0
- package/dist/plan/entry-ai-key.d.ts +3 -3
- package/dist/plan/entry-files-key.d.ts +3 -3
- package/dist/plan/entry-names-key.d.ts +73 -0
- package/dist/plan/entry-names-key.js +236 -0
- package/dist/plan/executor.d.ts +292 -24
- package/dist/plan/executor.js +745 -77
- package/dist/plan/index.d.ts +6 -2
- package/dist/plan/index.js +3 -1
- package/dist/plan/live.d.ts +9 -2
- package/dist/plan/login-host.d.ts +13 -2
- package/dist/plan/login-host.js +26 -7
- package/dist/plan/plan-apply.d.ts +153 -6
- package/dist/plan/plan-apply.js +639 -78
- package/dist/plan/platform-diff.d.ts +106 -1
- package/dist/plan/platform-diff.js +182 -2
- package/dist/plan/platform-org.d.ts +45 -1
- package/dist/plan/platform-org.js +34 -3
- package/dist/plan/platform-providers.d.ts +45 -1
- package/dist/plan/platform-providers.js +585 -16
- package/dist/plan/providers-readers.d.ts +2 -0
- package/dist/plan/providers-readers.js +4 -0
- package/dist/plan/rollout.d.ts +52 -0
- package/dist/plan/rollout.js +37 -0
- package/dist/plan/step-system.d.ts +22 -0
- package/dist/plan/step-system.js +38 -0
- package/dist/plan.d.ts +3 -0
- package/dist/platform.d.ts +22 -3
- package/dist/platform.js +6 -0
- package/dist/state.d.ts +13 -0
- package/dist/store/audit.js +15 -1
- package/dist/store/postgres.d.ts +1 -1
- package/dist/store/postgres.js +142 -15
- package/dist/store/schema.d.ts +202 -5
- package/dist/store/schema.js +18 -1
- package/dist/store.d.ts +47 -4
- package/dist/store.js +9 -1
- package/package.json +1 -1
package/dist/store/schema.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AppEnvSource, HostingEntry, IssuerApp, OwnerIdentity } from '../org.js';
|
|
2
2
|
import type { Plan } from '../plan.js';
|
|
3
|
-
import type { Checkpoint } from '../state.js';
|
|
3
|
+
import type { Checkpoint, DestroyRecord } from '../state.js';
|
|
4
4
|
/**
|
|
5
5
|
* Mirrors `migrations/0001_declared_org.sql`, which is the source of truth:
|
|
6
6
|
* the SQL carries the CHECKs drizzle-kit does not generate here (this
|
|
@@ -270,6 +270,40 @@ export declare const declaredOrgs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
270
270
|
identity: undefined;
|
|
271
271
|
generated: undefined;
|
|
272
272
|
}, {}, {}>;
|
|
273
|
+
callsVersionPinSynapse: import("drizzle-orm/pg-core").PgColumn<{
|
|
274
|
+
name: "calls_version_pin_synapse";
|
|
275
|
+
tableName: "foundry_declared_orgs";
|
|
276
|
+
dataType: "string";
|
|
277
|
+
columnType: "PgText";
|
|
278
|
+
data: string;
|
|
279
|
+
driverParam: string;
|
|
280
|
+
notNull: false;
|
|
281
|
+
hasDefault: false;
|
|
282
|
+
isPrimaryKey: false;
|
|
283
|
+
isAutoincrement: false;
|
|
284
|
+
hasRuntimeDefault: false;
|
|
285
|
+
enumValues: [string, ...string[]];
|
|
286
|
+
baseColumn: never;
|
|
287
|
+
identity: undefined;
|
|
288
|
+
generated: undefined;
|
|
289
|
+
}, {}, {}>;
|
|
290
|
+
callsVersionPinMas: import("drizzle-orm/pg-core").PgColumn<{
|
|
291
|
+
name: "calls_version_pin_mas";
|
|
292
|
+
tableName: "foundry_declared_orgs";
|
|
293
|
+
dataType: "string";
|
|
294
|
+
columnType: "PgText";
|
|
295
|
+
data: string;
|
|
296
|
+
driverParam: string;
|
|
297
|
+
notNull: false;
|
|
298
|
+
hasDefault: false;
|
|
299
|
+
isPrimaryKey: false;
|
|
300
|
+
isAutoincrement: false;
|
|
301
|
+
hasRuntimeDefault: false;
|
|
302
|
+
enumValues: [string, ...string[]];
|
|
303
|
+
baseColumn: never;
|
|
304
|
+
identity: undefined;
|
|
305
|
+
generated: undefined;
|
|
306
|
+
}, {}, {}>;
|
|
273
307
|
issuerUsesDomain: import("drizzle-orm/pg-core").PgColumn<{
|
|
274
308
|
name: "issuer_uses_domain";
|
|
275
309
|
tableName: "foundry_declared_orgs";
|
|
@@ -945,6 +979,101 @@ export declare const foundryAppliedState: import("drizzle-orm/pg-core").PgTableW
|
|
|
945
979
|
identity: undefined;
|
|
946
980
|
generated: undefined;
|
|
947
981
|
}, {}, {}>;
|
|
982
|
+
destroy: import("drizzle-orm/pg-core").PgColumn<{
|
|
983
|
+
name: "destroy";
|
|
984
|
+
tableName: "foundry_applied_state";
|
|
985
|
+
dataType: "json";
|
|
986
|
+
columnType: "PgJsonb";
|
|
987
|
+
data: DestroyRecord;
|
|
988
|
+
driverParam: unknown;
|
|
989
|
+
notNull: false;
|
|
990
|
+
hasDefault: false;
|
|
991
|
+
isPrimaryKey: false;
|
|
992
|
+
isAutoincrement: false;
|
|
993
|
+
hasRuntimeDefault: false;
|
|
994
|
+
enumValues: undefined;
|
|
995
|
+
baseColumn: never;
|
|
996
|
+
identity: undefined;
|
|
997
|
+
generated: undefined;
|
|
998
|
+
}, {}, {
|
|
999
|
+
$type: DestroyRecord;
|
|
1000
|
+
}>;
|
|
1001
|
+
};
|
|
1002
|
+
dialect: "pg";
|
|
1003
|
+
}>;
|
|
1004
|
+
/** Mirrors `migrations/0042_mutation_leases.sql`: one row per lock scope; `token` only ever rises (#441). */
|
|
1005
|
+
export declare const foundryMutationLeases: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1006
|
+
name: "foundry_mutation_leases";
|
|
1007
|
+
schema: undefined;
|
|
1008
|
+
columns: {
|
|
1009
|
+
scope: import("drizzle-orm/pg-core").PgColumn<{
|
|
1010
|
+
name: "scope";
|
|
1011
|
+
tableName: "foundry_mutation_leases";
|
|
1012
|
+
dataType: "string";
|
|
1013
|
+
columnType: "PgText";
|
|
1014
|
+
data: string;
|
|
1015
|
+
driverParam: string;
|
|
1016
|
+
notNull: true;
|
|
1017
|
+
hasDefault: false;
|
|
1018
|
+
isPrimaryKey: true;
|
|
1019
|
+
isAutoincrement: false;
|
|
1020
|
+
hasRuntimeDefault: false;
|
|
1021
|
+
enumValues: [string, ...string[]];
|
|
1022
|
+
baseColumn: never;
|
|
1023
|
+
identity: undefined;
|
|
1024
|
+
generated: undefined;
|
|
1025
|
+
}, {}, {}>;
|
|
1026
|
+
token: import("drizzle-orm/pg-core").PgColumn<{
|
|
1027
|
+
name: "token";
|
|
1028
|
+
tableName: "foundry_mutation_leases";
|
|
1029
|
+
dataType: "number";
|
|
1030
|
+
columnType: "PgBigInt53";
|
|
1031
|
+
data: number;
|
|
1032
|
+
driverParam: string | number;
|
|
1033
|
+
notNull: true;
|
|
1034
|
+
hasDefault: false;
|
|
1035
|
+
isPrimaryKey: false;
|
|
1036
|
+
isAutoincrement: false;
|
|
1037
|
+
hasRuntimeDefault: false;
|
|
1038
|
+
enumValues: undefined;
|
|
1039
|
+
baseColumn: never;
|
|
1040
|
+
identity: undefined;
|
|
1041
|
+
generated: undefined;
|
|
1042
|
+
}, {}, {}>;
|
|
1043
|
+
holder: import("drizzle-orm/pg-core").PgColumn<{
|
|
1044
|
+
name: "holder";
|
|
1045
|
+
tableName: "foundry_mutation_leases";
|
|
1046
|
+
dataType: "string";
|
|
1047
|
+
columnType: "PgText";
|
|
1048
|
+
data: string;
|
|
1049
|
+
driverParam: string;
|
|
1050
|
+
notNull: true;
|
|
1051
|
+
hasDefault: false;
|
|
1052
|
+
isPrimaryKey: false;
|
|
1053
|
+
isAutoincrement: false;
|
|
1054
|
+
hasRuntimeDefault: false;
|
|
1055
|
+
enumValues: [string, ...string[]];
|
|
1056
|
+
baseColumn: never;
|
|
1057
|
+
identity: undefined;
|
|
1058
|
+
generated: undefined;
|
|
1059
|
+
}, {}, {}>;
|
|
1060
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1061
|
+
name: "expires_at";
|
|
1062
|
+
tableName: "foundry_mutation_leases";
|
|
1063
|
+
dataType: "date";
|
|
1064
|
+
columnType: "PgTimestamp";
|
|
1065
|
+
data: Date;
|
|
1066
|
+
driverParam: string;
|
|
1067
|
+
notNull: true;
|
|
1068
|
+
hasDefault: false;
|
|
1069
|
+
isPrimaryKey: false;
|
|
1070
|
+
isAutoincrement: false;
|
|
1071
|
+
hasRuntimeDefault: false;
|
|
1072
|
+
enumValues: undefined;
|
|
1073
|
+
baseColumn: never;
|
|
1074
|
+
identity: undefined;
|
|
1075
|
+
generated: undefined;
|
|
1076
|
+
}, {}, {}>;
|
|
948
1077
|
};
|
|
949
1078
|
dialect: "pg";
|
|
950
1079
|
}>;
|
|
@@ -1107,7 +1236,7 @@ export declare const foundryAuditEvents: import("drizzle-orm/pg-core").PgTableWi
|
|
|
1107
1236
|
tableName: "foundry_audit_events";
|
|
1108
1237
|
dataType: "string";
|
|
1109
1238
|
columnType: "PgText";
|
|
1110
|
-
data: "
|
|
1239
|
+
data: "apply" | "plan" | "destroy";
|
|
1111
1240
|
driverParam: string;
|
|
1112
1241
|
notNull: true;
|
|
1113
1242
|
hasDefault: false;
|
|
@@ -1119,7 +1248,7 @@ export declare const foundryAuditEvents: import("drizzle-orm/pg-core").PgTableWi
|
|
|
1119
1248
|
identity: undefined;
|
|
1120
1249
|
generated: undefined;
|
|
1121
1250
|
}, {}, {
|
|
1122
|
-
$type: "
|
|
1251
|
+
$type: "apply" | "plan" | "destroy";
|
|
1123
1252
|
}>;
|
|
1124
1253
|
actorId: import("drizzle-orm/pg-core").PgColumn<{
|
|
1125
1254
|
name: "actor_id";
|
|
@@ -1177,7 +1306,7 @@ export declare const foundryAuditEvents: import("drizzle-orm/pg-core").PgTableWi
|
|
|
1177
1306
|
tableName: "foundry_audit_events";
|
|
1178
1307
|
dataType: "string";
|
|
1179
1308
|
columnType: "PgText";
|
|
1180
|
-
data: "applied" | "
|
|
1309
|
+
data: "applied" | "failed" | "refused" | "destroyed";
|
|
1181
1310
|
driverParam: string;
|
|
1182
1311
|
notNull: false;
|
|
1183
1312
|
hasDefault: false;
|
|
@@ -1189,7 +1318,7 @@ export declare const foundryAuditEvents: import("drizzle-orm/pg-core").PgTableWi
|
|
|
1189
1318
|
identity: undefined;
|
|
1190
1319
|
generated: undefined;
|
|
1191
1320
|
}, {}, {
|
|
1192
|
-
$type: "applied" | "
|
|
1321
|
+
$type: "applied" | "failed" | "refused" | "destroyed";
|
|
1193
1322
|
}>;
|
|
1194
1323
|
reason: import("drizzle-orm/pg-core").PgColumn<{
|
|
1195
1324
|
name: "reason";
|
|
@@ -1429,6 +1558,23 @@ export declare const foundryDeclaredPlatform: import("drizzle-orm/pg-core").PgTa
|
|
|
1429
1558
|
identity: undefined;
|
|
1430
1559
|
generated: undefined;
|
|
1431
1560
|
}, {}, {}>;
|
|
1561
|
+
mailLettermintProjectId: import("drizzle-orm/pg-core").PgColumn<{
|
|
1562
|
+
name: "mail_lettermint_project_id";
|
|
1563
|
+
tableName: "foundry_declared_platform";
|
|
1564
|
+
dataType: "string";
|
|
1565
|
+
columnType: "PgText";
|
|
1566
|
+
data: string;
|
|
1567
|
+
driverParam: string;
|
|
1568
|
+
notNull: false;
|
|
1569
|
+
hasDefault: false;
|
|
1570
|
+
isPrimaryKey: false;
|
|
1571
|
+
isAutoincrement: false;
|
|
1572
|
+
hasRuntimeDefault: false;
|
|
1573
|
+
enumValues: [string, ...string[]];
|
|
1574
|
+
baseColumn: never;
|
|
1575
|
+
identity: undefined;
|
|
1576
|
+
generated: undefined;
|
|
1577
|
+
}, {}, {}>;
|
|
1432
1578
|
sfuEnabled: import("drizzle-orm/pg-core").PgColumn<{
|
|
1433
1579
|
name: "sfu_enabled";
|
|
1434
1580
|
tableName: "foundry_declared_platform";
|
|
@@ -1735,6 +1881,57 @@ export declare const foundryDeclaredPlatform: import("drizzle-orm/pg-core").PgTa
|
|
|
1735
1881
|
identity: undefined;
|
|
1736
1882
|
generated: undefined;
|
|
1737
1883
|
}, {}, {}>;
|
|
1884
|
+
namesEnabled: import("drizzle-orm/pg-core").PgColumn<{
|
|
1885
|
+
name: "names_enabled";
|
|
1886
|
+
tableName: "foundry_declared_platform";
|
|
1887
|
+
dataType: "boolean";
|
|
1888
|
+
columnType: "PgBoolean";
|
|
1889
|
+
data: boolean;
|
|
1890
|
+
driverParam: boolean;
|
|
1891
|
+
notNull: true;
|
|
1892
|
+
hasDefault: true;
|
|
1893
|
+
isPrimaryKey: false;
|
|
1894
|
+
isAutoincrement: false;
|
|
1895
|
+
hasRuntimeDefault: false;
|
|
1896
|
+
enumValues: undefined;
|
|
1897
|
+
baseColumn: never;
|
|
1898
|
+
identity: undefined;
|
|
1899
|
+
generated: undefined;
|
|
1900
|
+
}, {}, {}>;
|
|
1901
|
+
namesHostname: import("drizzle-orm/pg-core").PgColumn<{
|
|
1902
|
+
name: "names_hostname";
|
|
1903
|
+
tableName: "foundry_declared_platform";
|
|
1904
|
+
dataType: "string";
|
|
1905
|
+
columnType: "PgText";
|
|
1906
|
+
data: string;
|
|
1907
|
+
driverParam: string;
|
|
1908
|
+
notNull: true;
|
|
1909
|
+
hasDefault: false;
|
|
1910
|
+
isPrimaryKey: false;
|
|
1911
|
+
isAutoincrement: false;
|
|
1912
|
+
hasRuntimeDefault: false;
|
|
1913
|
+
enumValues: [string, ...string[]];
|
|
1914
|
+
baseColumn: never;
|
|
1915
|
+
identity: undefined;
|
|
1916
|
+
generated: undefined;
|
|
1917
|
+
}, {}, {}>;
|
|
1918
|
+
namesGitRef: import("drizzle-orm/pg-core").PgColumn<{
|
|
1919
|
+
name: "names_git_ref";
|
|
1920
|
+
tableName: "foundry_declared_platform";
|
|
1921
|
+
dataType: "string";
|
|
1922
|
+
columnType: "PgText";
|
|
1923
|
+
data: string;
|
|
1924
|
+
driverParam: string;
|
|
1925
|
+
notNull: true;
|
|
1926
|
+
hasDefault: true;
|
|
1927
|
+
isPrimaryKey: false;
|
|
1928
|
+
isAutoincrement: false;
|
|
1929
|
+
hasRuntimeDefault: false;
|
|
1930
|
+
enumValues: [string, ...string[]];
|
|
1931
|
+
baseColumn: never;
|
|
1932
|
+
identity: undefined;
|
|
1933
|
+
generated: undefined;
|
|
1934
|
+
}, {}, {}>;
|
|
1738
1935
|
serviceIds: import("drizzle-orm/pg-core").PgColumn<{
|
|
1739
1936
|
name: "service_ids";
|
|
1740
1937
|
tableName: "foundry_declared_platform";
|
package/dist/store/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bigserial, boolean, integer, jsonb, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
|
|
1
|
+
import { bigint, bigserial, boolean, integer, jsonb, pgTable, text, timestamp, } from 'drizzle-orm/pg-core';
|
|
2
2
|
/**
|
|
3
3
|
* Mirrors `migrations/0001_declared_org.sql`, which is the source of truth:
|
|
4
4
|
* the SQL carries the CHECKs drizzle-kit does not generate here (this
|
|
@@ -31,6 +31,9 @@ export const declaredOrgs = pgTable('foundry_declared_orgs', {
|
|
|
31
31
|
chatUsesDomain: boolean('chat_uses_domain').notNull().default(false),
|
|
32
32
|
callsEnabled: boolean('calls_enabled').notNull().default(false),
|
|
33
33
|
callsUsesDomain: boolean('calls_uses_domain').notNull().default(false),
|
|
34
|
+
// #259: null holds no pin -- the stack follows versions.json, same as today.
|
|
35
|
+
callsVersionPinSynapse: text('calls_version_pin_synapse'),
|
|
36
|
+
callsVersionPinMas: text('calls_version_pin_mas'),
|
|
34
37
|
issuerUsesDomain: boolean('issuer_uses_domain').notNull().default(false),
|
|
35
38
|
// SiteConfig (org.ts, T10). A brand new org has no cms site.
|
|
36
39
|
siteEnabled: boolean('site_enabled').notNull().default(false),
|
|
@@ -101,6 +104,14 @@ export const foundryAppliedState = pgTable('foundry_applied_state', {
|
|
|
101
104
|
failedFields: jsonb('failed_fields').notNull().default([]).$type(),
|
|
102
105
|
lastAppliedAt: timestamp('last_applied_at', { withTimezone: true }),
|
|
103
106
|
lastAppliedDeclaredOrgVersion: text('last_applied_declared_org_version'),
|
|
107
|
+
destroy: jsonb('destroy').$type(),
|
|
108
|
+
});
|
|
109
|
+
/** Mirrors `migrations/0042_mutation_leases.sql`: one row per lock scope; `token` only ever rises (#441). */
|
|
110
|
+
export const foundryMutationLeases = pgTable('foundry_mutation_leases', {
|
|
111
|
+
scope: text('scope').primaryKey(),
|
|
112
|
+
token: bigint('token', { mode: 'number' }).notNull(),
|
|
113
|
+
holder: text('holder').notNull(),
|
|
114
|
+
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
|
104
115
|
});
|
|
105
116
|
/**
|
|
106
117
|
* Mirrors `migrations/0036_applied_versions.sql`, the source of truth: an
|
|
@@ -147,6 +158,8 @@ export const foundryDeclaredPlatform = pgTable('foundry_declared_platform', {
|
|
|
147
158
|
mailEnabled: boolean('mail_enabled').notNull().default(false),
|
|
148
159
|
mailHostname: text('mail_hostname').notNull(),
|
|
149
160
|
mailGitRef: text('mail_git_ref').notNull().default(''),
|
|
161
|
+
/** #491, `migrations/0044_platform_mail_lettermint_project.sql`. Declared, never discovered. */
|
|
162
|
+
mailLettermintProjectId: text('mail_lettermint_project_id'),
|
|
150
163
|
sfuEnabled: boolean('sfu_enabled').notNull().default(false),
|
|
151
164
|
sfuHostname: text('sfu_hostname').notNull(),
|
|
152
165
|
sfuGitRef: text('sfu_git_ref').notNull().default(''),
|
|
@@ -165,6 +178,10 @@ export const foundryDeclaredPlatform = pgTable('foundry_declared_platform', {
|
|
|
165
178
|
archonEnabled: boolean('archon_enabled').notNull().default(false),
|
|
166
179
|
archonHostname: text('archon_hostname').notNull(),
|
|
167
180
|
archonGitRef: text('archon_git_ref').notNull().default(''),
|
|
181
|
+
/** #317 (F7), `migrations/0038_platform_names.sql`. */
|
|
182
|
+
namesEnabled: boolean('names_enabled').notNull().default(false),
|
|
183
|
+
namesHostname: text('names_hostname').notNull(),
|
|
184
|
+
namesGitRef: text('names_git_ref').notNull().default(''),
|
|
168
185
|
/** `migrations/0018_platform_apply.sql`: the platform's applied state, `system:kind:key` to provider id. */
|
|
169
186
|
serviceIds: jsonb('service_ids').$type().notNull().default({}),
|
|
170
187
|
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
package/dist/store.d.ts
CHANGED
|
@@ -13,6 +13,24 @@ export interface StaleUpdate {
|
|
|
13
13
|
/** The org as it stands now. */
|
|
14
14
|
current: DeclaredOrg;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* A held mutation lease (#441). `token` rises on every acquire of a scope, so
|
|
18
|
+
* a worker whose lease expired and was taken over holds a token the store no
|
|
19
|
+
* longer accepts: its fenced writes are refused.
|
|
20
|
+
*/
|
|
21
|
+
export interface MutationLease {
|
|
22
|
+
scope: string;
|
|
23
|
+
token: number;
|
|
24
|
+
}
|
|
25
|
+
/** What `acquireMutationLease` returns while another holder has the scope: when that lease runs out. */
|
|
26
|
+
export interface HeldLease {
|
|
27
|
+
heldUntil: Date;
|
|
28
|
+
}
|
|
29
|
+
/** A fenced write (`putAppliedState`, `putServiceIds`) came from a lease that is no longer the current one (#441). Nothing was written. */
|
|
30
|
+
export declare class StaleLeaseError extends Error {
|
|
31
|
+
readonly scope: string;
|
|
32
|
+
constructor(scope: string);
|
|
33
|
+
}
|
|
16
34
|
/**
|
|
17
35
|
* The persistence seam https://github.com/wtfalch/foundry/issues/18
|
|
18
36
|
* implements: create, read and edit a {@link DeclaredOrg}, and read and
|
|
@@ -44,6 +62,12 @@ export interface DeclaredOrgStore {
|
|
|
44
62
|
* record instead.
|
|
45
63
|
*/
|
|
46
64
|
findOrgIdForZone(zoneId: string): Promise<OrgId | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Archon#271: an org other than `exceptOrgId` whose applied state records
|
|
67
|
+
* `id` as a Coolify app, database or project, or `null`. Adopt refuses a
|
|
68
|
+
* resource another org already holds.
|
|
69
|
+
*/
|
|
70
|
+
findOtherOrgRecordingCoolifyId(id: string, exceptOrgId: OrgId): Promise<OrgId | null>;
|
|
47
71
|
/**
|
|
48
72
|
* Combinations foundry knows are impossible are rejected with a reason
|
|
49
73
|
* (#18 "Done when"), so a caller must be ready for this to throw rather
|
|
@@ -58,7 +82,26 @@ export interface DeclaredOrgStore {
|
|
|
58
82
|
*/
|
|
59
83
|
update(id: OrgId, patch: Partial<DeclaredOrg>, opts: UpdateOptions): Promise<DeclaredOrg | StaleUpdate>;
|
|
60
84
|
getAppliedState(id: OrgId): Promise<AppliedState | null>;
|
|
61
|
-
|
|
85
|
+
/**
|
|
86
|
+
* With `fence` (#441), compare-and-set: the write happens only while
|
|
87
|
+
* `fence.token` is still the scope's current lease token, otherwise it
|
|
88
|
+
* throws {@link StaleLeaseError} and writes nothing.
|
|
89
|
+
*/
|
|
90
|
+
putAppliedState(state: AppliedState, fence?: MutationLease): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* #441: takes the exclusive mutation lease for `scope` (`company:<orgId>`
|
|
93
|
+
* or `platform`), or returns {@link HeldLease} while another holder's lease
|
|
94
|
+
* has not expired. Every successful acquire issues a higher token than the last.
|
|
95
|
+
*/
|
|
96
|
+
acquireMutationLease(scope: string, holder: string, ttlMs: number): Promise<MutationLease | HeldLease>;
|
|
97
|
+
/**
|
|
98
|
+
* Extends the lease to `ttlMs` from now, only while `lease.token` is still
|
|
99
|
+
* the scope's current token. Returns false once it is not: the holder lost
|
|
100
|
+
* the scope and must stop before its next provider step.
|
|
101
|
+
*/
|
|
102
|
+
renewMutationLease(lease: MutationLease, ttlMs: number): Promise<boolean>;
|
|
103
|
+
/** Frees the lease at once. A no-op if the lease was already taken over. */
|
|
104
|
+
releaseMutationLease(lease: MutationLease): Promise<void>;
|
|
62
105
|
/**
|
|
63
106
|
* Removes the declared org and its applied state together. Called only by
|
|
64
107
|
* `FoundryPlanApply.destroy` (`plan/plan-apply.ts`), once every resource it
|
|
@@ -68,7 +111,7 @@ export interface DeclaredOrgStore {
|
|
|
68
111
|
* not an error, so a retried destroy that reaches this step twice never
|
|
69
112
|
* throws.
|
|
70
113
|
*/
|
|
71
|
-
delete(id: OrgId): Promise<void>;
|
|
114
|
+
delete(id: OrgId, fence?: MutationLease): Promise<void>;
|
|
72
115
|
}
|
|
73
116
|
/**
|
|
74
117
|
* The persistence seam for #166's {@link DeclaredPlatform}, mirroring
|
|
@@ -87,8 +130,8 @@ export interface PlatformStore {
|
|
|
87
130
|
* before the first apply. `put` never touches it.
|
|
88
131
|
*/
|
|
89
132
|
getServiceIds(): Promise<Record<string, string>>;
|
|
90
|
-
/** Replaces the recorded ids. A no-op until the platform is declared. */
|
|
91
|
-
putServiceIds(serviceIds: Record<string, string
|
|
133
|
+
/** Replaces the recorded ids. A no-op until the platform is declared. With `fence` (#441), compare-and-set as {@link DeclaredOrgStore.putAppliedState}. */
|
|
134
|
+
putServiceIds(serviceIds: Record<string, string>, fence?: MutationLease): Promise<void>;
|
|
92
135
|
}
|
|
93
136
|
/**
|
|
94
137
|
* One recorded apply, appended to the history #253 keeps beside
|
package/dist/store.js
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/** A fenced write (`putAppliedState`, `putServiceIds`) came from a lease that is no longer the current one (#441). Nothing was written. */
|
|
2
|
+
export class StaleLeaseError extends Error {
|
|
3
|
+
scope;
|
|
4
|
+
constructor(scope) {
|
|
5
|
+
super(`mutation lease for ${scope} was lost to a newer holder; nothing written`);
|
|
6
|
+
this.scope = scope;
|
|
7
|
+
this.name = 'StaleLeaseError';
|
|
8
|
+
}
|
|
9
|
+
}
|