@fluidframework/container-runtime 2.41.0 → 2.42.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.
- package/CHANGELOG.md +4 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/channelCollection.d.ts +1 -1
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +4 -4
- package/dist/channelCollection.js.map +1 -1
- package/dist/compatUtils.d.ts +22 -1
- package/dist/compatUtils.d.ts.map +1 -1
- package/dist/compatUtils.js +109 -7
- package/dist/compatUtils.js.map +1 -1
- package/dist/containerRuntime.d.ts +34 -13
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +158 -59
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +5 -0
- package/dist/dataStore.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +2 -0
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +1 -1
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +5 -4
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +6 -5
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +9 -0
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +6 -4
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSerialization.d.ts +2 -1
- package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
- package/dist/opLifecycle/opSerialization.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +18 -5
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +20 -13
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +42 -18
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +62 -52
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/lib/channelCollection.d.ts +1 -1
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +4 -4
- package/lib/channelCollection.js.map +1 -1
- package/lib/compatUtils.d.ts +22 -1
- package/lib/compatUtils.d.ts.map +1 -1
- package/lib/compatUtils.js +102 -3
- package/lib/compatUtils.js.map +1 -1
- package/lib/containerRuntime.d.ts +34 -13
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +160 -61
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +5 -0
- package/lib/dataStore.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +2 -0
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +1 -1
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +5 -4
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/metadata.d.ts +1 -1
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +6 -5
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +9 -0
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +6 -4
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSerialization.d.ts +2 -1
- package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
- package/lib/opLifecycle/opSerialization.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +18 -5
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +20 -13
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +42 -18
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +62 -52
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js.map +1 -1
- package/package.json +18 -18
- package/src/channelCollection.ts +4 -4
- package/src/compatUtils.ts +145 -10
- package/src/containerRuntime.ts +209 -73
- package/src/dataStore.ts +7 -0
- package/src/gc/garbageCollection.ts +2 -0
- package/src/gc/gcDefinitions.ts +1 -1
- package/src/index.ts +2 -1
- package/src/messageTypes.ts +12 -5
- package/src/metadata.ts +1 -1
- package/src/opLifecycle/definitions.ts +7 -3
- package/src/opLifecycle/index.ts +1 -0
- package/src/opLifecycle/opGroupingManager.ts +17 -4
- package/src/opLifecycle/opSerialization.ts +6 -1
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +49 -22
- package/src/summary/documentSchema.ts +111 -86
- package/src/summary/index.ts +2 -1
|
@@ -59,26 +59,42 @@ export type IdCompressorMode = "on" | "delayed" | undefined;
|
|
|
59
59
|
* @internal
|
|
60
60
|
*/
|
|
61
61
|
export interface IDocumentSchema {
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
62
|
+
// Note: Incoming schemas from other clients may have additional root-level properties (i.e. IDocumentSchema.app)
|
|
63
|
+
// that this client does not understand. The runtime will ignore these properties, unless they are within the
|
|
64
|
+
// "runtime" sub-tree, in which case it will fail if it is unable to understand any runtime properties.
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Describes how data needed to understand the schema is stored in this structure.
|
|
68
|
+
* If runtime sees a version it does not understand, it should immediately fail and not
|
|
69
|
+
* attempt to interpret any further data.
|
|
70
|
+
*/
|
|
65
71
|
version: number;
|
|
66
72
|
|
|
67
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Sequence number when this schema became active.
|
|
75
|
+
*/
|
|
68
76
|
refSeq: number;
|
|
69
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Runtime configurations that affect the document schema. Other clients must understand these
|
|
80
|
+
* properties to be able to open the document.
|
|
81
|
+
*/
|
|
70
82
|
runtime: Record<string, DocumentSchemaValueType>;
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
/**
|
|
74
86
|
* Content of the type=ContainerMessageType.DocumentSchemaChange ops.
|
|
75
|
-
*
|
|
76
|
-
* ContainerMessageType.DocumentSchemaChange messages use CAS (Compare-and-swap) semantics, and convey
|
|
77
|
-
* regSeq of last known schema change (known to a client proposing schema change).
|
|
78
|
-
* @see ContainerRuntimeDocumentSchemaMessage
|
|
87
|
+
* @see InboundContainerRuntimeDocumentSchemaMessage
|
|
79
88
|
* @internal
|
|
80
89
|
*/
|
|
81
|
-
export type
|
|
90
|
+
export type IDocumentSchemaChangeMessageIncoming = IDocumentSchema;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Similar to {@link IDocumentSchemaChangeMessageIncoming}, but used for outgoing schema messages.
|
|
94
|
+
* @see OutboundContainerRuntimeDocumentSchemaMessage
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
export type IDocumentSchemaChangeMessageOutgoing = IDocumentSchemaCurrent;
|
|
82
98
|
|
|
83
99
|
/**
|
|
84
100
|
* Settings that this session would like to have, based on options and feature gates.
|
|
@@ -113,9 +129,12 @@ export interface IDocumentSchemaFeatures {
|
|
|
113
129
|
|
|
114
130
|
/**
|
|
115
131
|
* Current version known properties that define document schema
|
|
116
|
-
* This must be bumped whenever the format of document schema or protocol for changing the current document schema changes
|
|
117
|
-
*
|
|
118
|
-
* Ex:
|
|
132
|
+
* This must be bumped whenever the format of document schema or protocol for changing the current document schema changes
|
|
133
|
+
* in a way that all old/new clients are required to understand.
|
|
134
|
+
* Ex: Adding a new configuration property (under IDocumentSchema.runtime) does not require changing this version since there is logic
|
|
135
|
+
* in old clients for handling new/unknown properties.
|
|
136
|
+
* Ex: Changing the 'document schema acceptance' mechanism from convert-and-swap to one requiring consensus does require changing this version
|
|
137
|
+
* since all clients need to understand the new protocol.
|
|
119
138
|
* @internal
|
|
120
139
|
*/
|
|
121
140
|
export const currentDocumentVersionSchema = 1;
|
|
@@ -124,31 +143,29 @@ export const currentDocumentVersionSchema = 1;
|
|
|
124
143
|
* Current document schema.
|
|
125
144
|
* @internal
|
|
126
145
|
*/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
version:
|
|
130
|
-
refSeq: number;
|
|
131
|
-
|
|
146
|
+
export interface IDocumentSchemaCurrent extends Required<IDocumentSchema> {
|
|
147
|
+
// This is the version of the schema that we currently understand.
|
|
148
|
+
version: typeof currentDocumentVersionSchema;
|
|
132
149
|
runtime: {
|
|
133
150
|
[P in keyof IDocumentSchemaFeatures]?: IDocumentSchemaFeatures[P] extends boolean
|
|
134
151
|
? true
|
|
135
152
|
: IDocumentSchemaFeatures[P];
|
|
136
153
|
};
|
|
137
|
-
}
|
|
154
|
+
}
|
|
138
155
|
|
|
139
156
|
interface IProperty<T = unknown> {
|
|
140
|
-
and: (
|
|
141
|
-
or: (
|
|
157
|
+
and: (persistedSchema: T, providedSchema: T) => T;
|
|
158
|
+
or: (persistedSchema: T, providedSchema: T) => T;
|
|
142
159
|
validate(t: unknown): boolean;
|
|
143
160
|
}
|
|
144
161
|
|
|
145
162
|
class TrueOrUndefined implements IProperty<true | undefined> {
|
|
146
|
-
public and(
|
|
147
|
-
return
|
|
163
|
+
public and(persistedSchema?: true, providedSchema?: true): true | undefined {
|
|
164
|
+
return persistedSchema === true && providedSchema === true ? true : undefined;
|
|
148
165
|
}
|
|
149
166
|
|
|
150
|
-
public or(
|
|
151
|
-
return
|
|
167
|
+
public or(persistedSchema?: true, providedSchema?: true): true | undefined {
|
|
168
|
+
return persistedSchema === true || providedSchema === true ? true : undefined;
|
|
152
169
|
}
|
|
153
170
|
|
|
154
171
|
public validate(t: unknown): t is true | undefined {
|
|
@@ -157,32 +174,32 @@ class TrueOrUndefined implements IProperty<true | undefined> {
|
|
|
157
174
|
}
|
|
158
175
|
|
|
159
176
|
class TrueOrUndefinedMax extends TrueOrUndefined {
|
|
160
|
-
public and(
|
|
161
|
-
return this.or(
|
|
177
|
+
public and(persistedSchema?: true, providedSchema?: true): true | undefined {
|
|
178
|
+
return this.or(persistedSchema, providedSchema);
|
|
162
179
|
}
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
class MultiChoice implements IProperty<string | undefined> {
|
|
166
183
|
constructor(private readonly choices: string[]) {}
|
|
167
184
|
|
|
168
|
-
public and(
|
|
169
|
-
if (
|
|
185
|
+
public and(persistedSchema?: string, providedSchema?: string): string | undefined {
|
|
186
|
+
if (persistedSchema === undefined || providedSchema === undefined) {
|
|
170
187
|
return undefined;
|
|
171
188
|
}
|
|
172
189
|
return this.choices[
|
|
173
|
-
Math.min(this.choices.indexOf(
|
|
190
|
+
Math.min(this.choices.indexOf(persistedSchema), this.choices.indexOf(providedSchema))
|
|
174
191
|
];
|
|
175
192
|
}
|
|
176
193
|
|
|
177
|
-
public or(
|
|
178
|
-
if (
|
|
179
|
-
return
|
|
194
|
+
public or(persistedSchema?: string, providedSchema?: string): string | undefined {
|
|
195
|
+
if (persistedSchema === undefined) {
|
|
196
|
+
return providedSchema;
|
|
180
197
|
}
|
|
181
|
-
if (
|
|
182
|
-
return
|
|
198
|
+
if (providedSchema === undefined) {
|
|
199
|
+
return persistedSchema;
|
|
183
200
|
}
|
|
184
201
|
return this.choices[
|
|
185
|
-
Math.max(this.choices.indexOf(
|
|
202
|
+
Math.max(this.choices.indexOf(persistedSchema), this.choices.indexOf(providedSchema))
|
|
186
203
|
];
|
|
187
204
|
}
|
|
188
205
|
|
|
@@ -193,26 +210,26 @@ class MultiChoice implements IProperty<string | undefined> {
|
|
|
193
210
|
|
|
194
211
|
class IdCompressorProperty extends MultiChoice {
|
|
195
212
|
// document schema always wins!
|
|
196
|
-
public and(
|
|
197
|
-
return
|
|
213
|
+
public and(persistedSchema?: string, providedSchema?: string): string | undefined {
|
|
214
|
+
return persistedSchema;
|
|
198
215
|
}
|
|
199
216
|
}
|
|
200
217
|
|
|
201
218
|
class CheckVersions implements IProperty<string[] | undefined> {
|
|
202
219
|
public or(
|
|
203
|
-
|
|
204
|
-
|
|
220
|
+
persistedSchema: string[] = [],
|
|
221
|
+
providedSchema: string[] = [],
|
|
205
222
|
): string[] | undefined {
|
|
206
|
-
const set = new Set<string>([...
|
|
223
|
+
const set = new Set<string>([...persistedSchema, ...providedSchema]);
|
|
207
224
|
return arrayToProp([...set.values()]);
|
|
208
225
|
}
|
|
209
226
|
|
|
210
227
|
// Once version is there, it stays there forever.
|
|
211
228
|
public and(
|
|
212
|
-
|
|
213
|
-
|
|
229
|
+
persistedSchema: string[] = [],
|
|
230
|
+
providedSchema: string[] = [],
|
|
214
231
|
): string[] | undefined {
|
|
215
|
-
return this.or(
|
|
232
|
+
return this.or(persistedSchema, providedSchema);
|
|
216
233
|
}
|
|
217
234
|
|
|
218
235
|
public validate(t: unknown): boolean {
|
|
@@ -240,7 +257,7 @@ const documentSchemaSupportedConfigs = {
|
|
|
240
257
|
function checkRuntimeCompatibility(
|
|
241
258
|
documentSchema: IDocumentSchema | undefined,
|
|
242
259
|
schemaName: string,
|
|
243
|
-
):
|
|
260
|
+
): asserts documentSchema is IDocumentSchemaCurrent {
|
|
244
261
|
// Back-compat - we can't do anything about legacy documents.
|
|
245
262
|
// There is no way to validate them, so we are taking a guess that safe deployment processes used by a given app
|
|
246
263
|
// do not run into compat problems.
|
|
@@ -298,59 +315,59 @@ function checkRuntimeCompatibility(
|
|
|
298
315
|
}
|
|
299
316
|
|
|
300
317
|
function and(
|
|
301
|
-
|
|
302
|
-
|
|
318
|
+
persistedSchema: IDocumentSchemaCurrent,
|
|
319
|
+
providedSchema: IDocumentSchemaCurrent,
|
|
303
320
|
): IDocumentSchemaCurrent {
|
|
304
321
|
const runtime = {};
|
|
305
322
|
for (const key of new Set([
|
|
306
|
-
...Object.keys(
|
|
307
|
-
...Object.keys(
|
|
323
|
+
...Object.keys(persistedSchema.runtime),
|
|
324
|
+
...Object.keys(providedSchema.runtime),
|
|
308
325
|
])) {
|
|
309
326
|
runtime[key] = (documentSchemaSupportedConfigs[key] as IProperty).and(
|
|
310
|
-
|
|
311
|
-
|
|
327
|
+
persistedSchema.runtime[key],
|
|
328
|
+
providedSchema.runtime[key],
|
|
312
329
|
);
|
|
313
330
|
}
|
|
314
331
|
return {
|
|
315
332
|
version: currentDocumentVersionSchema,
|
|
316
|
-
refSeq:
|
|
333
|
+
refSeq: persistedSchema.refSeq,
|
|
317
334
|
runtime,
|
|
318
|
-
}
|
|
335
|
+
};
|
|
319
336
|
}
|
|
320
337
|
|
|
321
338
|
function or(
|
|
322
|
-
|
|
323
|
-
|
|
339
|
+
persistedSchema: IDocumentSchemaCurrent,
|
|
340
|
+
providedSchema: IDocumentSchemaCurrent,
|
|
324
341
|
): IDocumentSchemaCurrent {
|
|
325
342
|
const runtime = {};
|
|
326
343
|
for (const key of new Set([
|
|
327
|
-
...Object.keys(
|
|
328
|
-
...Object.keys(
|
|
344
|
+
...Object.keys(persistedSchema.runtime),
|
|
345
|
+
...Object.keys(providedSchema.runtime),
|
|
329
346
|
])) {
|
|
330
347
|
runtime[key] = (documentSchemaSupportedConfigs[key] as IProperty).or(
|
|
331
|
-
|
|
332
|
-
|
|
348
|
+
persistedSchema.runtime[key],
|
|
349
|
+
providedSchema.runtime[key],
|
|
333
350
|
);
|
|
334
351
|
}
|
|
335
352
|
return {
|
|
336
353
|
version: currentDocumentVersionSchema,
|
|
337
|
-
refSeq:
|
|
354
|
+
refSeq: persistedSchema.refSeq,
|
|
338
355
|
runtime,
|
|
339
|
-
}
|
|
356
|
+
};
|
|
340
357
|
}
|
|
341
358
|
|
|
342
359
|
function same(
|
|
343
|
-
|
|
344
|
-
|
|
360
|
+
persistedSchema: IDocumentSchemaCurrent,
|
|
361
|
+
providedSchema: IDocumentSchemaCurrent,
|
|
345
362
|
): boolean {
|
|
346
363
|
for (const key of new Set([
|
|
347
|
-
...Object.keys(
|
|
348
|
-
...Object.keys(
|
|
364
|
+
...Object.keys(persistedSchema.runtime),
|
|
365
|
+
...Object.keys(providedSchema.runtime),
|
|
349
366
|
])) {
|
|
350
367
|
// If schemas differ only by type of behavior, then we should not send schema change ops!
|
|
351
368
|
if (
|
|
352
369
|
key !== "explicitSchemaControl" &&
|
|
353
|
-
|
|
370
|
+
persistedSchema.runtime[key] !== providedSchema.runtime[key]
|
|
354
371
|
) {
|
|
355
372
|
return false;
|
|
356
373
|
}
|
|
@@ -436,10 +453,15 @@ function arrayToProp(arr: string[]): string[] | undefined {
|
|
|
436
453
|
*/
|
|
437
454
|
export class DocumentsSchemaController {
|
|
438
455
|
private explicitSchemaControl: boolean;
|
|
439
|
-
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Have we generated a DocumentSchemaChange op and we're waiting for the ack?
|
|
459
|
+
* This is used to ensure that we do not generate multiple schema change ops - this client should only ever send one (if any).
|
|
460
|
+
*/
|
|
461
|
+
private opPending = false;
|
|
440
462
|
|
|
441
463
|
// schema coming from document metadata (snapshot we loaded from)
|
|
442
|
-
private documentSchema:
|
|
464
|
+
private documentSchema: IDocumentSchema;
|
|
443
465
|
|
|
444
466
|
// desired schema, based on feature gates / runtime options.
|
|
445
467
|
// This includes requests to enable to disable functionality
|
|
@@ -491,9 +513,9 @@ export class DocumentsSchemaController {
|
|
|
491
513
|
|
|
492
514
|
// Schema coming from document metadata (snapshot we loaded from), or if no document exists
|
|
493
515
|
// (this is a new document) then this is the same as desiredSchema (same as session schema in such case).
|
|
494
|
-
// Latter is
|
|
516
|
+
// Latter is important sure that's what will go into summary.
|
|
495
517
|
this.documentSchema = existing
|
|
496
|
-
? (
|
|
518
|
+
? (documentMetadataSchema ??
|
|
497
519
|
({
|
|
498
520
|
version: currentDocumentVersionSchema,
|
|
499
521
|
// see comment in summarizeDocumentSchema() on why it has to stay zero
|
|
@@ -542,14 +564,15 @@ export class DocumentsSchemaController {
|
|
|
542
564
|
checkRuntimeCompatibility(this.futureSchema, "future");
|
|
543
565
|
}
|
|
544
566
|
|
|
545
|
-
public summarizeDocumentSchema(
|
|
567
|
+
public summarizeDocumentSchema(
|
|
568
|
+
refSeq: number,
|
|
569
|
+
): IDocumentSchema | IDocumentSchemaCurrent | undefined {
|
|
546
570
|
// For legacy behavior, we could write nothing (return undefined).
|
|
547
571
|
// It does not buy us anything, as whatever written in summary does not actually impact clients operating in legacy mode.
|
|
548
572
|
// But writing current used config (and assuming most of the clients settle on same config over time) will help with transition
|
|
549
573
|
// out of legacy mode, as clients transitioning out of it would be able to use all the
|
|
550
574
|
// features that are mentioned in schema right away, without a need to go through schema transition (and thus for a session or
|
|
551
575
|
// two losing ability to use all the features)
|
|
552
|
-
|
|
553
576
|
const schema = this.explicitSchemaControl ? this.documentSchema : this.desiredSchema;
|
|
554
577
|
|
|
555
578
|
// It's important to keep refSeq at zero in legacy mode, such that transition out of it is simple and we do not have
|
|
@@ -567,20 +590,17 @@ export class DocumentsSchemaController {
|
|
|
567
590
|
/**
|
|
568
591
|
* Called by Container runtime whenever it is about to send some op.
|
|
569
592
|
* It gives opportunity for controller to issue its own ops - we do not want to send ops if there are no local changes in document.
|
|
570
|
-
* Please consider note above constructor about race conditions - current design is to
|
|
593
|
+
* Please consider note above constructor about race conditions - current design is to generate op only once in a session lifetime.
|
|
571
594
|
* @returns Optional message to send.
|
|
572
595
|
*/
|
|
573
|
-
public
|
|
574
|
-
if (this.
|
|
575
|
-
this.
|
|
596
|
+
public maybeGenerateSchemaMessage(): IDocumentSchemaChangeMessageOutgoing | undefined {
|
|
597
|
+
if (this.futureSchema !== undefined && !this.opPending) {
|
|
598
|
+
this.opPending = true;
|
|
576
599
|
assert(
|
|
577
600
|
this.explicitSchemaControl && this.futureSchema.runtime.explicitSchemaControl === true,
|
|
578
601
|
0x94e /* not legacy */,
|
|
579
602
|
);
|
|
580
|
-
return
|
|
581
|
-
...this.futureSchema,
|
|
582
|
-
refSeq: this.documentSchema.refSeq,
|
|
583
|
-
};
|
|
603
|
+
return this.futureSchema;
|
|
584
604
|
}
|
|
585
605
|
}
|
|
586
606
|
|
|
@@ -612,7 +632,7 @@ export class DocumentsSchemaController {
|
|
|
612
632
|
* @returns - true if schema was accepted, otherwise false (rejected due to failed CAS)
|
|
613
633
|
*/
|
|
614
634
|
public processDocumentSchemaMessages(
|
|
615
|
-
contents:
|
|
635
|
+
contents: IDocumentSchemaChangeMessageIncoming[],
|
|
616
636
|
local: boolean,
|
|
617
637
|
sequenceNumber: number,
|
|
618
638
|
): boolean {
|
|
@@ -639,10 +659,12 @@ export class DocumentsSchemaController {
|
|
|
639
659
|
|
|
640
660
|
// Changes are in effect. Immediately check that this client understands these changes
|
|
641
661
|
checkRuntimeCompatibility(content, "change");
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
662
|
+
const schema = {
|
|
663
|
+
...content,
|
|
664
|
+
refSeq: sequenceNumber,
|
|
665
|
+
} satisfies IDocumentSchemaCurrent;
|
|
666
|
+
this.documentSchema = schema;
|
|
667
|
+
this.sessionSchema = and(schema, this.desiredSchema);
|
|
646
668
|
assert(this.sessionSchema.refSeq === sequenceNumber, 0x97d /* seq# */);
|
|
647
669
|
|
|
648
670
|
// legacy behavior is automatically off for the document once someone sends a schema op -
|
|
@@ -663,8 +685,11 @@ export class DocumentsSchemaController {
|
|
|
663
685
|
return true;
|
|
664
686
|
}
|
|
665
687
|
|
|
666
|
-
|
|
667
|
-
|
|
688
|
+
/**
|
|
689
|
+
* Indicates the pending op was not ack'd and we may try to send it again if needed.
|
|
690
|
+
*/
|
|
691
|
+
public pendingOpNotAcked(): void {
|
|
692
|
+
this.opPending = false;
|
|
668
693
|
}
|
|
669
694
|
}
|
|
670
695
|
|
package/src/summary/index.ts
CHANGED
|
@@ -106,7 +106,8 @@ export {
|
|
|
106
106
|
currentDocumentVersionSchema,
|
|
107
107
|
DocumentSchemaValueType,
|
|
108
108
|
DocumentsSchemaController,
|
|
109
|
-
|
|
109
|
+
IDocumentSchemaChangeMessageIncoming,
|
|
110
|
+
IDocumentSchemaChangeMessageOutgoing,
|
|
110
111
|
IDocumentSchemaFeatures,
|
|
111
112
|
} from "./documentSchema.js";
|
|
112
113
|
export {
|