@dcl/sdk 7.29.1-35901015152.commit-d1b7b96 → 7.29.1-36041177279.commit-502e633
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/atom.d.ts +19 -0
- package/atom.js +83 -0
- package/future.d.ts +8 -0
- package/future.js +26 -0
- package/internal/language-events.d.ts +1 -0
- package/internal/language-events.js +8 -0
- package/internal/transports/rendererTransport.js +5 -2
- package/network/binary-message-bus.d.ts +6 -3
- package/network/binary-message-bus.js +9 -5
- package/network/chunking.d.ts +5 -0
- package/network/chunking.js +38 -0
- package/network/events/implementation.d.ts +93 -0
- package/network/events/implementation.js +221 -0
- package/network/events/index.d.ts +42 -0
- package/network/events/index.js +43 -0
- package/network/events/protocol.d.ts +27 -0
- package/network/events/protocol.js +66 -0
- package/network/events/registry.d.ts +8 -0
- package/network/events/registry.js +3 -0
- package/network/index.d.ts +8 -2
- package/network/index.js +16 -3
- package/network/message-bus-sync.d.ts +16 -3
- package/network/message-bus-sync.js +161 -103
- package/network/server/index.d.ts +14 -0
- package/network/server/index.js +219 -0
- package/network/server/utils.d.ts +18 -0
- package/network/server/utils.js +135 -0
- package/network/state.js +3 -5
- package/observables.d.ts +4 -0
- package/observables.js +6 -1
- package/package.json +6 -6
- package/platform/index.d.ts +16 -0
- package/platform/index.js +42 -1
- package/players/index.d.ts +0 -1
- package/players/index.js +6 -4
- package/server/env-var.d.ts +15 -0
- package/server/env-var.js +31 -0
- package/server/index.d.ts +2 -0
- package/server/index.js +3 -0
- package/server/storage/constants.d.ts +80 -0
- package/server/storage/constants.js +19 -0
- package/server/storage/error-message.d.ts +1 -0
- package/server/storage/error-message.js +9 -0
- package/server/storage/index.d.ts +54 -0
- package/server/storage/index.js +60 -0
- package/server/storage/player.d.ts +60 -0
- package/server/storage/player.js +244 -0
- package/server/storage/scene.d.ts +55 -0
- package/server/storage/scene.js +232 -0
- package/server/storage/serialize.d.ts +1 -0
- package/server/storage/serialize.js +135 -0
- package/server/storage/value-cache.d.ts +1 -0
- package/server/storage/value-cache.js +67 -0
- package/server/storage/write-queue.d.ts +1 -0
- package/server/storage/write-queue.js +113 -0
- package/server/storage-url.d.ts +13 -0
- package/server/storage-url.js +42 -0
- package/server/utils.d.ts +35 -0
- package/server/utils.js +69 -0
- package/src/atom.ts +98 -0
- package/src/future.ts +38 -0
- package/src/internal/language-events.ts +8 -0
- package/src/internal/transports/rendererTransport.ts +4 -1
- package/src/network/binary-message-bus.ts +9 -4
- package/src/network/chunking.ts +45 -0
- package/src/network/events/implementation.ts +271 -0
- package/src/network/events/index.ts +48 -0
- package/src/network/events/protocol.ts +94 -0
- package/src/network/events/registry.ts +18 -0
- package/src/network/index.ts +40 -3
- package/src/network/message-bus-sync.ts +176 -112
- package/src/network/server/index.ts +301 -0
- package/src/network/server/utils.ts +189 -0
- package/src/network/state.ts +3 -4
- package/src/observables.ts +10 -0
- package/src/platform/index.ts +47 -0
- package/src/players/index.ts +5 -4
- package/src/server/env-var.ts +36 -0
- package/src/server/index.ts +12 -0
- package/src/server/storage/constants.ts +112 -0
- package/src/server/storage/error-message.ts +8 -0
- package/src/server/storage/index.ts +83 -0
- package/src/server/storage/player.ts +345 -0
- package/src/server/storage/scene.ts +324 -0
- package/src/server/storage/serialize.ts +132 -0
- package/src/server/storage/value-cache.ts +119 -0
- package/src/server/storage/write-queue.ts +174 -0
- package/src/server/storage-url.ts +49 -0
- package/src/server/utils.ts +83 -0
- package/src/testing/runtime.ts +3 -0
- package/testing/runtime.js +4 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { getStorageServerUrl } from '../storage-url';
|
|
2
|
+
import { assertIsServer, wrapSignedFetch } from '../utils';
|
|
3
|
+
import { createStorageConfig, MODULE_NAME } from './constants';
|
|
4
|
+
import { createValueCache } from './value-cache';
|
|
5
|
+
import { errorMessage } from './error-message';
|
|
6
|
+
import { assertStorageKey, serializeStorageValue } from './serialize';
|
|
7
|
+
import { createWriteQueue, SupersedingWriteFailed } from './write-queue';
|
|
8
|
+
/**
|
|
9
|
+
* Creates scene-scoped storage that provides methods to interact with
|
|
10
|
+
* scene-specific key-value pairs from the Server Side Storage service.
|
|
11
|
+
* This module only works when running on server-side scenes.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export const createSceneStorage = (config = createStorageConfig()) => {
|
|
15
|
+
const cache = createValueCache(config);
|
|
16
|
+
// Each in-flight GET is tracked by a wrapper object whose identity marks
|
|
17
|
+
// ownership: a landed write detaches the pending GET so its stale response is not cached.
|
|
18
|
+
const inflightGets = new Map();
|
|
19
|
+
// Writes to the same key are serialized (and rapid ones coalesced to the
|
|
20
|
+
// latest value) so the service commits them in issue order — overlapping
|
|
21
|
+
// PUTs would otherwise leave both the kept value and the cached value to
|
|
22
|
+
// response-order chance.
|
|
23
|
+
const writes = createWriteQueue();
|
|
24
|
+
async function executeSet(key, body) {
|
|
25
|
+
let baseUrl;
|
|
26
|
+
try {
|
|
27
|
+
baseUrl = await getStorageServerUrl();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
cache.delete(key);
|
|
31
|
+
console.error(`Failed to set storage value '${key}': ${errorMessage(error)}`);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const url = `${baseUrl}/values/${encodeURIComponent(key)}`;
|
|
35
|
+
const [error] = await wrapSignedFetch({
|
|
36
|
+
url,
|
|
37
|
+
init: {
|
|
38
|
+
method: 'PUT',
|
|
39
|
+
headers: {
|
|
40
|
+
'content-type': 'application/json'
|
|
41
|
+
},
|
|
42
|
+
body
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// Either way the entry changed server-side (or may have): detach any
|
|
46
|
+
// overlapping in-flight GET so its stale response is not cached.
|
|
47
|
+
inflightGets.delete(key);
|
|
48
|
+
if (error) {
|
|
49
|
+
// The PUT may have reached the server, so the cached body is no
|
|
50
|
+
// longer reliable.
|
|
51
|
+
cache.delete(key);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
cache.set(key, { body });
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
async function executeDelete(key) {
|
|
58
|
+
let baseUrl;
|
|
59
|
+
try {
|
|
60
|
+
baseUrl = await getStorageServerUrl();
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
cache.delete(key);
|
|
64
|
+
throw new Error(`Failed to delete storage value '${key}': ${errorMessage(error)}`);
|
|
65
|
+
}
|
|
66
|
+
const url = `${baseUrl}/values/${encodeURIComponent(key)}`;
|
|
67
|
+
const [error, , status] = await wrapSignedFetch({
|
|
68
|
+
url,
|
|
69
|
+
init: {
|
|
70
|
+
method: 'DELETE',
|
|
71
|
+
headers: {}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
// Detach again: a GET may have started while the DELETE was in flight.
|
|
75
|
+
inflightGets.delete(key);
|
|
76
|
+
if (error) {
|
|
77
|
+
// A 404 still confirms the key is absent server-side.
|
|
78
|
+
if (status === 404) {
|
|
79
|
+
cache.setAbsent(key);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
// The DELETE may have reached the server, so the cached body is unreliable.
|
|
83
|
+
cache.delete(key);
|
|
84
|
+
throw new Error(`Failed to delete storage value '${key}': ${errorMessage(error)}`);
|
|
85
|
+
}
|
|
86
|
+
cache.setAbsent(key);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
async get(key, options) {
|
|
91
|
+
assertIsServer(MODULE_NAME);
|
|
92
|
+
assertStorageKey(key, 'Storage.get()');
|
|
93
|
+
if (writes.isPending(key))
|
|
94
|
+
await writes.settled(key);
|
|
95
|
+
if (config.cacheReads && !options?.fresh) {
|
|
96
|
+
const entry = cache.get(key);
|
|
97
|
+
if (entry?.absent)
|
|
98
|
+
return null;
|
|
99
|
+
// Parse per hit so each caller gets a fresh object (no shared mutation).
|
|
100
|
+
if (entry?.body !== undefined)
|
|
101
|
+
return JSON.parse(entry.body).value;
|
|
102
|
+
}
|
|
103
|
+
// Coalesce concurrent gets (even fresh ones: an in-flight response is
|
|
104
|
+
// milliseconds old, not TTL-stale) into a single network request.
|
|
105
|
+
const joined = inflightGets.get(key);
|
|
106
|
+
if (joined)
|
|
107
|
+
return joined.promise;
|
|
108
|
+
const inflight = {};
|
|
109
|
+
inflight.promise = (async () => {
|
|
110
|
+
try {
|
|
111
|
+
let baseUrl;
|
|
112
|
+
try {
|
|
113
|
+
baseUrl = await getStorageServerUrl();
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`Failed to get storage value '${key}': ${errorMessage(error)}`);
|
|
117
|
+
}
|
|
118
|
+
const url = `${baseUrl}/values/${encodeURIComponent(key)}`;
|
|
119
|
+
const [error, data, status] = await wrapSignedFetch({ url });
|
|
120
|
+
const isOwner = inflightGets.get(key) === inflight;
|
|
121
|
+
if (error) {
|
|
122
|
+
// A confirmed 404 is a first-class "absent" outcome, not a failure.
|
|
123
|
+
if (status === 404) {
|
|
124
|
+
if (isOwner)
|
|
125
|
+
cache.setAbsent(key);
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
throw new Error(`Failed to get storage value '${key}': ${errorMessage(error)}`);
|
|
129
|
+
}
|
|
130
|
+
// wrapSignedFetch parses an empty 2xx body as {}: a missing value is a fault, not an absence.
|
|
131
|
+
if (!data || data.value === undefined) {
|
|
132
|
+
throw new Error(`Failed to get storage value '${key}': response carried no value`);
|
|
133
|
+
}
|
|
134
|
+
// Same serialization shape as set()'s PUT body, so a read followed by
|
|
135
|
+
// an unchanged write can be skipped.
|
|
136
|
+
const body = JSON.stringify({ value: data.value });
|
|
137
|
+
if (isOwner)
|
|
138
|
+
cache.set(key, { body });
|
|
139
|
+
return data.value;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
if (inflightGets.get(key) === inflight)
|
|
143
|
+
inflightGets.delete(key);
|
|
144
|
+
}
|
|
145
|
+
})();
|
|
146
|
+
inflightGets.set(key, inflight);
|
|
147
|
+
return inflight.promise;
|
|
148
|
+
},
|
|
149
|
+
async set(key, value, options) {
|
|
150
|
+
assertIsServer(MODULE_NAME);
|
|
151
|
+
assertStorageKey(key, 'Storage.set()');
|
|
152
|
+
const body = serializeStorageValue(value, `Storage.set('${key}')`);
|
|
153
|
+
const skipIfUnchanged = options?.skipIfUnchanged ?? config.skipIfUnchanged;
|
|
154
|
+
// Dedup against confirmed state only while no write is pending — a
|
|
155
|
+
// pending write makes the cache momentarily stale; enqueue() coalesces
|
|
156
|
+
// against pending writes instead.
|
|
157
|
+
if (skipIfUnchanged && writes.pending(key) === undefined && cache.get(key)?.body === body) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return writes.enqueue(key, body, (b) => executeSet(key, b), skipIfUnchanged);
|
|
161
|
+
},
|
|
162
|
+
async delete(key) {
|
|
163
|
+
assertIsServer(MODULE_NAME);
|
|
164
|
+
assertStorageKey(key, 'Storage.delete()');
|
|
165
|
+
return writes
|
|
166
|
+
.enqueue(key, null, () => executeDelete(key), true)
|
|
167
|
+
.catch((error) => {
|
|
168
|
+
if (error instanceof SupersedingWriteFailed) {
|
|
169
|
+
throw new Error(`Failed to delete storage value '${key}': ${error.message}`);
|
|
170
|
+
}
|
|
171
|
+
throw error;
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
async getValues(options) {
|
|
175
|
+
assertIsServer(MODULE_NAME);
|
|
176
|
+
const { prefix, limit, offset } = options ?? {};
|
|
177
|
+
let baseUrl;
|
|
178
|
+
try {
|
|
179
|
+
baseUrl = await getStorageServerUrl();
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
throw new Error(`Failed to get storage values: ${errorMessage(error)}`);
|
|
183
|
+
}
|
|
184
|
+
const parts = [];
|
|
185
|
+
if (!!prefix) {
|
|
186
|
+
parts.push(`prefix=${encodeURIComponent(prefix)}`);
|
|
187
|
+
}
|
|
188
|
+
if (!!limit) {
|
|
189
|
+
parts.push(`limit=${limit}`);
|
|
190
|
+
}
|
|
191
|
+
if (!!offset) {
|
|
192
|
+
parts.push(`offset=${offset}`);
|
|
193
|
+
}
|
|
194
|
+
const query = parts.join('&');
|
|
195
|
+
const url = query ? `${baseUrl}/values?${query}` : `${baseUrl}/values`;
|
|
196
|
+
const watcher = cache.watch();
|
|
197
|
+
const [error, response] = await wrapSignedFetch({ url });
|
|
198
|
+
watcher.stop();
|
|
199
|
+
if (error) {
|
|
200
|
+
throw new Error(`Failed to get storage values: ${errorMessage(error)}`);
|
|
201
|
+
}
|
|
202
|
+
const data = response?.data;
|
|
203
|
+
if (!Array.isArray(data)) {
|
|
204
|
+
throw new Error('Failed to get storage values: response carried no data array');
|
|
205
|
+
}
|
|
206
|
+
if (data.some((entry) => typeof entry?.key !== 'string' || entry.value === undefined)) {
|
|
207
|
+
throw new Error('Failed to get storage values: response carried a malformed entry');
|
|
208
|
+
}
|
|
209
|
+
// Seed the per-key cache so subsequent get()/set() on returned keys can
|
|
210
|
+
// skip the network. Only keys with no live entry and no pending write
|
|
211
|
+
// are seeded: existing per-key state comes from a confirmed operation
|
|
212
|
+
// that this page snapshot — whose request started earlier — must not
|
|
213
|
+
// clobber with stale data. Absence is never seeded (prefix/pagination
|
|
214
|
+
// make it non-authoritative). A page larger than cacheMaxEntries churns
|
|
215
|
+
// the cache; entries repopulate lazily.
|
|
216
|
+
for (const entry of data) {
|
|
217
|
+
if (watcher.mutated(entry.key) || writes.isPending(entry.key) || inflightGets.has(entry.key))
|
|
218
|
+
continue;
|
|
219
|
+
if (cache.get(entry.key) === undefined) {
|
|
220
|
+
cache.set(entry.key, { body: JSON.stringify({ value: entry.value }) });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const requestedOffset = offset ?? 0;
|
|
224
|
+
const pagination = {
|
|
225
|
+
offset: response.pagination?.offset ?? requestedOffset,
|
|
226
|
+
total: response.pagination?.total ?? data.length
|
|
227
|
+
};
|
|
228
|
+
return { data, pagination };
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NlbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmVyL3N0b3JhZ2Uvc2NlbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFDMUQsT0FBTyxFQUNMLG1CQUFtQixFQUluQixXQUFXLEVBR1osTUFBTSxhQUFhLENBQUE7QUFDcEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUM5QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLHNCQUFzQixFQUFFLE1BQU0sZUFBZSxDQUFBO0FBNER4RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsU0FBNkIsbUJBQW1CLEVBQUUsRUFBaUIsRUFBRTtJQUN0RyxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUN0Qyx5RUFBeUU7SUFDekUsMEZBQTBGO0lBQzFGLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxFQUF5QyxDQUFBO0lBQ3JFLHlFQUF5RTtJQUN6RSx5RUFBeUU7SUFDekUseUVBQXlFO0lBQ3pFLHlCQUF5QjtJQUN6QixNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsRUFBRSxDQUFBO0lBRWpDLEtBQUssVUFBVSxVQUFVLENBQUMsR0FBVyxFQUFFLElBQVk7UUFDakQsSUFBSSxPQUFlLENBQUE7UUFDbkIsSUFBSTtZQUNGLE9BQU8sR0FBRyxNQUFNLG1CQUFtQixFQUFFLENBQUE7U0FDdEM7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLEtBQUssQ0FB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SUFBSSxDQUFDLENBQUE7WUFDbkMsTUFBTSxVQUFVLEdBQUc7Z0JBQ2pCLE1BQU0sRUFBRSxRQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sSUFBSSxlQUFlO2dCQUN2RCxLQUFLLEVBQUUsUUFBUyxDQUFDLFVBQVUsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU07YUFDbEQsQ0FBQTtZQUVELE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUE7UUFDN0IsQ0FBQztLQUNGLENBQUE7QUFDSCxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRTdG9yYWdlU2VydmVyVXJsIH0gZnJvbSAnLi4vc3RvcmFnZS11cmwnXG5pbXBvcnQgeyBhc3NlcnRJc1NlcnZlciwgd3JhcFNpZ25lZEZldGNoIH0gZnJvbSAnLi4vdXRpbHMnXG5pbXBvcnQge1xuICBjcmVhdGVTdG9yYWdlQ29uZmlnLFxuICBHZXRPcHRpb25zLFxuICBHZXRWYWx1ZXNPcHRpb25zLFxuICBHZXRWYWx1ZXNSZXN1bHQsXG4gIE1PRFVMRV9OQU1FLFxuICBTZXRPcHRpb25zLFxuICBTdG9yYWdlQ29uZmlnU3RhdGVcbn0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBjcmVhdGVWYWx1ZUNhY2hlIH0gZnJvbSAnLi92YWx1ZS1jYWNoZSdcbmltcG9ydCB7IGVycm9yTWVzc2FnZSB9IGZyb20gJy4vZXJyb3ItbWVzc2FnZSdcbmltcG9ydCB7IGFzc2VydFN0b3JhZ2VLZXksIHNlcmlhbGl6ZVN0b3JhZ2VWYWx1ZSB9IGZyb20gJy4vc2VyaWFsaXplJ1xuaW1wb3J0IHsgY3JlYXRlV3JpdGVRdWV1ZSwgU3VwZXJzZWRpbmdXcml0ZUZhaWxlZCB9IGZyb20gJy4vd3JpdGUtcXVldWUnXG5cbi8qKlxuICogU2NlbmUtc2NvcGVkIHN0b3JhZ2UgaW50ZXJmYWNlIGZvciBrZXktdmFsdWUgcGFpcnMgZnJvbSB0aGUgU2VydmVyIFNpZGUgU3RvcmFnZSBzZXJ2aWNlLlxuICogVGhpcyBpcyBOT1QgZmlsZXN5c3RlbSBzdG9yYWdlIC0gZGF0YSBpcyBzdG9yZWQgaW4gdGhlIHJlbW90ZSBzdG9yYWdlIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVNjZW5lU3RvcmFnZSB7XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHNjZW5lIHN0b3JhZ2UgYnkga2V5IGZyb20gdGhlIFNlcnZlciBTaWRlIFN0b3JhZ2Ugc2VydmljZS5cbiAgICpcbiAgICogQnkgZGVmYXVsdCAoY2FjaGVSZWFkcyksIHZhbHVlcyByZWFkIG9yIHdyaXR0ZW4gZHVyaW5nIHRoZSBsYXN0IGNhY2hlTWF4QWdlTXNcbiAgICogYXJlIHNlcnZlZCBmcm9tIGEgbG9jYWwgY2FjaGUgd2l0aG91dCBhIG5ldHdvcmsgcmVxdWVzdCwgaW5jbHVkaW5nIGNvbmZpcm1lZFxuICAgKiBcIm5vdCBmb3VuZFwiIHJlc3VsdHMuIENvbmN1cnJlbnQgZ2V0cyBmb3IgdGhlIHNhbWUga2V5IHNoYXJlIG9uZSByZXF1ZXN0LlxuICAgKiBPdXQtb2YtYmFuZCB3cml0ZXJzIChlLmcuIENMSSBzdG9yYWdlIGNvbW1hbmRzKSBtYXkgbm90IGJlIHZpc2libGUgZm9yIHVwIHRvXG4gICAqIGNhY2hlTWF4QWdlTXMg4oCUIHBhc3MgeyBmcmVzaDogdHJ1ZSB9IHRvIGZvcmNlIGEgbmV0d29yayByZWFkLlxuICAgKiBBIHJlYWQgZmlyc3Qgd2FpdHMgZm9yIHdyaXRlcyB0byB0aGUgc2FtZSBrZXkgdGhhdCB3ZXJlIHBlbmRpbmcgd2hlbiBpdCB3YXNcbiAgICogaXNzdWVkLCBzbyBpdCByZWZsZWN0cyBldmVyeSB3cml0ZSBpc3N1ZWQgYmVmb3JlIGl0LlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSB0byByZXRyaWV2ZVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHsgZnJlc2ggfSB0byBieXBhc3MgdGhlIHJlYWQgY2FjaGVcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHBhcnNlZCBKU09OIHZhbHVlLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSByZWFkIGZhaWxzLCBzbyBhIGZhaWx1cmUgaXMgbmV2ZXIgbWlzdGFrZW4gZm9yIGEgbWlzc2luZyBrZXlcbiAgICogQHRocm93cyBUeXBlRXJyb3IgaWYgdGhlIGtleSBpcyBpbnZhbGlkXG4gICAqL1xuICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBvcHRpb25zPzogR2V0T3B0aW9ucyk6IFByb21pc2U8VCB8IG51bGw+XG5cbiAgLyoqXG4gICAqIFN0b3JlcyBhIHZhbHVlIGluIHNjZW5lIHN0b3JhZ2UgaW4gdGhlIFNlcnZlciBTaWRlIFN0b3JhZ2Ugc2VydmljZS5cbiAgICogQHBhcmFtIGtleSAtIFRoZSBrZXkgdG8gc3RvcmUgdGhlIHZhbHVlIHVuZGVyXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBzdG9yZSAod2lsbCBiZSBKU09OIHNlcmlhbGl6ZWQpXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwgeyBza2lwSWZVbmNoYW5nZWQgfSB0byBza2lwIHRoZSBuZXR3b3JrIHdyaXRlIHdoZW4gdGhlIHZhbHVlIGlzIGFscmVhZHkgc3RvcmVkXG4gICAqIEByZXR1cm5zIHRydWUgb25jZSBzdG9yZWQsIG9yIG9uY2UgYSBuZXdlciB3cml0ZSB0aGF0IHJlcGxhY2VkIHRoaXMgb25lIGxhbmRzXG4gICAqIChyYXBpZCB3cml0ZXMgY29hbGVzY2UpOyBmYWxzZSBpZiB0aGUgd3JpdGUsIG9yIGl0cyByZXBsYWNlbWVudCwgZmFpbHNcbiAgICogQHRocm93cyBUeXBlRXJyb3IgaWYgdGhlIGtleSBpcyBpbnZhbGlkLCBvciB0aGUgdmFsdWUgY2Fubm90IGJlIHN0b3JlZCB1bmNoYW5nZWQ6IHVuZGVmaW5lZCxcbiAgICogY2lyY3VsYXIsIGEgQmlnSW50LCBvciBjb250YWluaW5nIGEgZnVuY3Rpb24sIGEgc3ltYm9sLCBhIG5vbi1maW5pdGUgbnVtYmVyLCBhbiB1bmRlZmluZWQgYXJyYXlcbiAgICogZWxlbWVudCBvciBob2xlLCBhIE1hcCwgU2V0LCB0eXBlZCBhcnJheSBvciBvdGhlciBidWlsdC1pbiB3aXRoIG5vIEpTT04gZm9ybSwgb3IgdGV4dCB3aXRoIGFuXG4gICAqIHVucGFpcmVkIHN1cnJvZ2F0ZSBvciBhIE5VTCBjaGFyYWN0ZXIuIEFuIHVuZGVmaW5lZCBvYmplY3QgcHJvcGVydHkgaXMgZHJvcHBlZDsgYSBEYXRlIGlzXG4gICAqIHN0b3JlZCBhcyBpdHMgSVNPIHN0cmluZyBhbmQgYSBjbGFzcyBpbnN0YW5jZSBhcyBpdHMgb3duIGVudW1lcmFibGUgZGF0YS5cbiAgICovXG4gIHNldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHZhbHVlOiBULCBvcHRpb25zPzogU2V0T3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj5cblxuICAvKipcbiAgICogRGVsZXRlcyBhIHZhbHVlIGZyb20gc2NlbmUgc3RvcmFnZSBpbiB0aGUgU2VydmVyIFNpZGUgU3RvcmFnZSBzZXJ2aWNlLlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSB0byBkZWxldGVcbiAgICogQHJldHVybnMgdHJ1ZSBvbmNlIGFwcGxpZWQsIG9yIG9uY2UgYSBuZXdlciB3cml0ZSB0aGF0IHJlcGxhY2VkIGl0IGxhbmRzO1xuICAgKiBmYWxzZSBvbmx5IGZvciBhIGNvbmZpcm1lZCA0MDRcbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgZGVsZXRlLCBvciBpdHMgcmVwbGFjZW1lbnQsIGZhaWxzOyBhIGZhaWx1cmUgaXMgbmV2ZXIgcmVwb3J0ZWQgYXMgYWJzZW5jZVxuICAgKiBAdGhyb3dzIFR5cGVFcnJvciBpZiB0aGUga2V5IGlzIGludmFsaWRcbiAgICovXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj5cblxuICAvKipcbiAgICogUmV0dXJucyBrZXktdmFsdWUgZW50cmllcyBmcm9tIHNjZW5lIHN0b3JhZ2UsIG9wdGlvbmFsbHkgZmlsdGVyZWQgYnkgcHJlZml4LlxuICAgKiBTdXBwb3J0cyBwYWdpbmF0aW9uIHZpYSBsaW1pdCBhbmQgb2Zmc2V0LlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHsgcHJlZml4LCBsaW1pdCwgb2Zmc2V0IH0gZm9yIGZpbHRlcmluZyBhbmQgcGFnaW5hdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8geyBkYXRhLCBwYWdpbmF0aW9uOiB7IG9mZnNldCwgdG90YWwgfSB9IGZvciBwYWdpbmF0aW9uIFVJXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIHJlYWQgZmFpbHMsIHNvIGEgZmFpbHVyZSBpcyBuZXZlciBtaXN0YWtlbiBmb3IgYW4gZW1wdHkgcGFnZVxuICAgKi9cbiAgZ2V0VmFsdWVzKG9wdGlvbnM/OiBHZXRWYWx1ZXNPcHRpb25zKTogUHJvbWlzZTxHZXRWYWx1ZXNSZXN1bHQ+XG59XG5cbi8qKlxuICogQ3JlYXRlcyBzY2VuZS1zY29wZWQgc3RvcmFnZSB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgdG8gaW50ZXJhY3Qgd2l0aFxuICogc2NlbmUtc3BlY2lmaWMga2V5LXZhbHVlIHBhaXJzIGZyb20gdGhlIFNlcnZlciBTaWRlIFN0b3JhZ2Ugc2VydmljZS5cbiAqIFRoaXMgbW9kdWxlIG9ubHkgd29ya3Mgd2hlbiBydW5uaW5nIG9uIHNlcnZlci1zaWRlIHNjZW5lcy5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlU2NlbmVTdG9yYWdlID0gKGNvbmZpZzogU3RvcmFnZUNvbmZpZ1N0YXRlID0gY3JlYXRlU3RvcmFnZUNvbmZpZygpKTogSVNjZW5lU3RvcmFnZSA9PiB7XG4gIGNvbnN0IGNhY2hlID0gY3JlYXRlVmFsdWVDYWNoZShjb25maWcpXG4gIC8vIEVhY2ggaW4tZmxpZ2h0IEdFVCBpcyB0cmFja2VkIGJ5IGEgd3JhcHBlciBvYmplY3Qgd2hvc2UgaWRlbnRpdHkgbWFya3NcbiAgLy8gb3duZXJzaGlwOiBhIGxhbmRlZCB3cml0ZSBkZXRhY2hlcyB0aGUgcGVuZGluZyBHRVQgc28gaXRzIHN0YWxlIHJlc3BvbnNlIGlzIG5vdCBjYWNoZWQuXG4gIGNvbnN0IGluZmxpZ2h0R2V0cyA9IG5ldyBNYXA8c3RyaW5nLCB7IHByb21pc2U6IFByb21pc2U8dW5rbm93bj4gfT4oKVxuICAvLyBXcml0ZXMgdG8gdGhlIHNhbWUga2V5IGFyZSBzZXJpYWxpemVkIChhbmQgcmFwaWQgb25lcyBjb2FsZXNjZWQgdG8gdGhlXG4gIC8vIGxhdGVzdCB2YWx1ZSkgc28gdGhlIHNlcnZpY2UgY29tbWl0cyB0aGVtIGluIGlzc3VlIG9yZGVyIOKAlCBvdmVybGFwcGluZ1xuICAvLyBQVVRzIHdvdWxkIG90aGVyd2lzZSBsZWF2ZSBib3RoIHRoZSBrZXB0IHZhbHVlIGFuZCB0aGUgY2FjaGVkIHZhbHVlIHRvXG4gIC8vIHJlc3BvbnNlLW9yZGVyIGNoYW5jZS5cbiAgY29uc3Qgd3JpdGVzID0gY3JlYXRlV3JpdGVRdWV1ZSgpXG5cbiAgYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZVNldChrZXk6IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbGV0IGJhc2VVcmw6IHN0cmluZ1xuICAgIHRyeSB7XG4gICAgICBiYXNlVXJsID0gYXdhaXQgZ2V0U3RvcmFnZVNlcnZlclVybCgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhY2hlLmRlbGV0ZShrZXkpXG4gICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gc2V0IHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGNvbnN0IHVybCA9IGAke2Jhc2VVcmx9L3ZhbHVlcy8ke2VuY29kZVVSSUNvbXBvbmVudChrZXkpfWBcblxuICAgIGNvbnN0IFtlcnJvcl0gPSBhd2FpdCB3cmFwU2lnbmVkRmV0Y2goe1xuICAgICAgdXJsLFxuICAgICAgaW5pdDoge1xuICAgICAgICBtZXRob2Q6ICdQVVQnLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICB9LFxuICAgICAgICBib2R5XG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIEVpdGhlciB3YXkgdGhlIGVudHJ5IGNoYW5nZWQgc2VydmVyLXNpZGUgKG9yIG1heSBoYXZlKTogZGV0YWNoIGFueVxuICAgIC8vIG92ZXJsYXBwaW5nIGluLWZsaWdodCBHRVQgc28gaXRzIHN0YWxlIHJlc3BvbnNlIGlzIG5vdCBjYWNoZWQuXG4gICAgaW5mbGlnaHRHZXRzLmRlbGV0ZShrZXkpXG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIC8vIFRoZSBQVVQgbWF5IGhhdmUgcmVhY2hlZCB0aGUgc2VydmVyLCBzbyB0aGUgY2FjaGVkIGJvZHkgaXMgbm9cbiAgICAgIC8vIGxvbmdlciByZWxpYWJsZS5cbiAgICAgIGNhY2hlLmRlbGV0ZShrZXkpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjYWNoZS5zZXQoa2V5LCB7IGJvZHkgfSlcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZURlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxldCBiYXNlVXJsOiBzdHJpbmdcbiAgICB0cnkge1xuICAgICAgYmFzZVVybCA9IGF3YWl0IGdldFN0b3JhZ2VTZXJ2ZXJVcmwoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjYWNoZS5kZWxldGUoa2V5KVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZGVsZXRlIHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgIH1cbiAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfS92YWx1ZXMvJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX1gXG5cbiAgICBjb25zdCBbZXJyb3IsICwgc3RhdHVzXSA9IGF3YWl0IHdyYXBTaWduZWRGZXRjaCh7XG4gICAgICB1cmwsXG4gICAgICBpbml0OiB7XG4gICAgICAgIG1ldGhvZDogJ0RFTEVURScsXG4gICAgICAgIGhlYWRlcnM6IHt9XG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIERldGFjaCBhZ2FpbjogYSBHRVQgbWF5IGhhdmUgc3RhcnRlZCB3aGlsZSB0aGUgREVMRVRFIHdhcyBpbiBmbGlnaHQuXG4gICAgaW5mbGlnaHRHZXRzLmRlbGV0ZShrZXkpXG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIC8vIEEgNDA0IHN0aWxsIGNvbmZpcm1zIHRoZSBrZXkgaXMgYWJzZW50IHNlcnZlci1zaWRlLlxuICAgICAgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgIGNhY2hlLnNldEFic2VudChrZXkpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgLy8gVGhlIERFTEVURSBtYXkgaGF2ZSByZWFjaGVkIHRoZSBzZXJ2ZXIsIHNvIHRoZSBjYWNoZWQgYm9keSBpcyB1bnJlbGlhYmxlLlxuICAgICAgY2FjaGUuZGVsZXRlKGtleSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBzdG9yYWdlIHZhbHVlICcke2tleX0nOiAke2Vycm9yTWVzc2FnZShlcnJvcil9YClcbiAgICB9XG5cbiAgICBjYWNoZS5zZXRBYnNlbnQoa2V5KVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiBHZXRPcHRpb25zKTogUHJvbWlzZTxUIHwgbnVsbD4ge1xuICAgICAgYXNzZXJ0SXNTZXJ2ZXIoTU9EVUxFX05BTUUpXG4gICAgICBhc3NlcnRTdG9yYWdlS2V5KGtleSwgJ1N0b3JhZ2UuZ2V0KCknKVxuXG4gICAgICBpZiAod3JpdGVzLmlzUGVuZGluZyhrZXkpKSBhd2FpdCB3cml0ZXMuc2V0dGxlZChrZXkpXG5cbiAgICAgIGlmIChjb25maWcuY2FjaGVSZWFkcyAmJiAhb3B0aW9ucz8uZnJlc2gpIHtcbiAgICAgICAgY29uc3QgZW50cnkgPSBjYWNoZS5nZXQoa2V5KVxuICAgICAgICBpZiAoZW50cnk/LmFic2VudCkgcmV0dXJuIG51bGxcbiAgICAgICAgLy8gUGFyc2UgcGVyIGhpdCBzbyBlYWNoIGNhbGxlciBnZXRzIGEgZnJlc2ggb2JqZWN0IChubyBzaGFyZWQgbXV0YXRpb24pLlxuICAgICAgICBpZiAoZW50cnk/LmJvZHkgIT09IHVuZGVmaW5lZCkgcmV0dXJuIEpTT04ucGFyc2UoZW50cnkuYm9keSkudmFsdWUgYXMgVFxuICAgICAgfVxuXG4gICAgICAvLyBDb2FsZXNjZSBjb25jdXJyZW50IGdldHMgKGV2ZW4gZnJlc2ggb25lczogYW4gaW4tZmxpZ2h0IHJlc3BvbnNlIGlzXG4gICAgICAvLyBtaWxsaXNlY29uZHMgb2xkLCBub3QgVFRMLXN0YWxlKSBpbnRvIGEgc2luZ2xlIG5ldHdvcmsgcmVxdWVzdC5cbiAgICAgIGNvbnN0IGpvaW5lZCA9IGluZmxpZ2h0R2V0cy5nZXQoa2V5KVxuICAgICAgaWYgKGpvaW5lZCkgcmV0dXJuIGpvaW5lZC5wcm9taXNlIGFzIFByb21pc2U8VCB8IG51bGw+XG5cbiAgICAgIGNvbnN0IGluZmxpZ2h0ID0ge30gYXMgeyBwcm9taXNlOiBQcm9taXNlPFQgfCBudWxsPiB9XG4gICAgICBpbmZsaWdodC5wcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsZXQgYmFzZVVybDogc3RyaW5nXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGJhc2VVcmwgPSBhd2FpdCBnZXRTdG9yYWdlU2VydmVyVXJsKClcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfS92YWx1ZXMvJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX1gXG5cbiAgICAgICAgICBjb25zdCBbZXJyb3IsIGRhdGEsIHN0YXR1c10gPSBhd2FpdCB3cmFwU2lnbmVkRmV0Y2g8eyB2YWx1ZTogVCB9Pih7IHVybCB9KVxuXG4gICAgICAgICAgY29uc3QgaXNPd25lciA9IGluZmxpZ2h0R2V0cy5nZXQoa2V5KSA9PT0gaW5mbGlnaHRcblxuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgLy8gQSBjb25maXJtZWQgNDA0IGlzIGEgZmlyc3QtY2xhc3MgXCJhYnNlbnRcIiBvdXRjb21lLCBub3QgYSBmYWlsdXJlLlxuICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgICAgICAgIGlmIChpc093bmVyKSBjYWNoZS5zZXRBYnNlbnQoa2V5KVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHdyYXBTaWduZWRGZXRjaCBwYXJzZXMgYW4gZW1wdHkgMnh4IGJvZHkgYXMge306IGEgbWlzc2luZyB2YWx1ZSBpcyBhIGZhdWx0LCBub3QgYW4gYWJzZW5jZS5cbiAgICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgc3RvcmFnZSB2YWx1ZSAnJHtrZXl9JzogcmVzcG9uc2UgY2FycmllZCBubyB2YWx1ZWApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU2FtZSBzZXJpYWxpemF0aW9uIHNoYXBlIGFzIHNldCgpJ3MgUFVUIGJvZHksIHNvIGEgcmVhZCBmb2xsb3dlZCBieVxuICAgICAgICAgIC8vIGFuIHVuY2hhbmdlZCB3cml0ZSBjYW4gYmUgc2tpcHBlZC5cbiAgICAgICAgICBjb25zdCBib2R5ID0gSlNPTi5zdHJpbmdpZnkoeyB2YWx1ZTogZGF0YS52YWx1ZSB9KVxuICAgICAgICAgIGlmIChpc093bmVyKSBjYWNoZS5zZXQoa2V5LCB7IGJvZHkgfSlcbiAgICAgICAgICByZXR1cm4gZGF0YS52YWx1ZVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChpbmZsaWdodEdldHMuZ2V0KGtleSkgPT09IGluZmxpZ2h0KSBpbmZsaWdodEdldHMuZGVsZXRlKGtleSlcbiAgICAgICAgfVxuICAgICAgfSkoKVxuXG4gICAgICBpbmZsaWdodEdldHMuc2V0KGtleSwgaW5mbGlnaHQpXG4gICAgICByZXR1cm4gaW5mbGlnaHQucHJvbWlzZVxuICAgIH0sXG5cbiAgICBhc3luYyBzZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCB2YWx1ZTogVCwgb3B0aW9ucz86IFNldE9wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGFzc2VydElzU2VydmVyKE1PRFVMRV9OQU1FKVxuICAgICAgYXNzZXJ0U3RvcmFnZUtleShrZXksICdTdG9yYWdlLnNldCgpJylcblxuICAgICAgY29uc3QgYm9keSA9IHNlcmlhbGl6ZVN0b3JhZ2VWYWx1ZSh2YWx1ZSwgYFN0b3JhZ2Uuc2V0KCcke2tleX0nKWApXG4gICAgICBjb25zdCBza2lwSWZVbmNoYW5nZWQgPSBvcHRpb25zPy5za2lwSWZVbmNoYW5nZWQgPz8gY29uZmlnLnNraXBJZlVuY2hhbmdlZFxuXG4gICAgICAvLyBEZWR1cCBhZ2FpbnN0IGNvbmZpcm1lZCBzdGF0ZSBvbmx5IHdoaWxlIG5vIHdyaXRlIGlzIHBlbmRpbmcg4oCUIGFcbiAgICAgIC8vIHBlbmRpbmcgd3JpdGUgbWFrZXMgdGhlIGNhY2hlIG1vbWVudGFyaWx5IHN0YWxlOyBlbnF1ZXVlKCkgY29hbGVzY2VzXG4gICAgICAvLyBhZ2FpbnN0IHBlbmRpbmcgd3JpdGVzIGluc3RlYWQuXG4gICAgICBpZiAoc2tpcElmVW5jaGFuZ2VkICYmIHdyaXRlcy5wZW5kaW5nKGtleSkgPT09IHVuZGVmaW5lZCAmJiBjYWNoZS5nZXQoa2V5KT8uYm9keSA9PT0gYm9keSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gd3JpdGVzLmVucXVldWUoa2V5LCBib2R5LCAoYikgPT4gZXhlY3V0ZVNldChrZXksIGIgYXMgc3RyaW5nKSwgc2tpcElmVW5jaGFuZ2VkKVxuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGUoa2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGFzc2VydElzU2VydmVyKE1PRFVMRV9OQU1FKVxuICAgICAgYXNzZXJ0U3RvcmFnZUtleShrZXksICdTdG9yYWdlLmRlbGV0ZSgpJylcblxuICAgICAgcmV0dXJuIHdyaXRlc1xuICAgICAgICAuZW5xdWV1ZShrZXksIG51bGwsICgpID0+IGV4ZWN1dGVEZWxldGUoa2V5KSwgdHJ1ZSlcbiAgICAgICAgLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFN1cGVyc2VkaW5nV3JpdGVGYWlsZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBzdG9yYWdlIHZhbHVlICcke2tleX0nOiAke2Vycm9yLm1lc3NhZ2V9YClcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgfSlcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0VmFsdWVzKG9wdGlvbnM/OiBHZXRWYWx1ZXNPcHRpb25zKTogUHJvbWlzZTxHZXRWYWx1ZXNSZXN1bHQ+IHtcbiAgICAgIGFzc2VydElzU2VydmVyKE1PRFVMRV9OQU1FKVxuXG4gICAgICBjb25zdCB7IHByZWZpeCwgbGltaXQsIG9mZnNldCB9ID0gb3B0aW9ucyA/PyB7fVxuICAgICAgbGV0IGJhc2VVcmw6IHN0cmluZ1xuICAgICAgdHJ5IHtcbiAgICAgICAgYmFzZVVybCA9IGF3YWl0IGdldFN0b3JhZ2VTZXJ2ZXJVcmwoKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHN0b3JhZ2UgdmFsdWVzOiAke2Vycm9yTWVzc2FnZShlcnJvcil9YClcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICAgIGlmICghIXByZWZpeCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGBwcmVmaXg9JHtlbmNvZGVVUklDb21wb25lbnQocHJlZml4KX1gKVxuICAgICAgfVxuXG4gICAgICBpZiAoISFsaW1pdCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGBsaW1pdD0ke2xpbWl0fWApXG4gICAgICB9XG5cbiAgICAgIGlmICghIW9mZnNldCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGBvZmZzZXQ9JHtvZmZzZXR9YClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcXVlcnkgPSBwYXJ0cy5qb2luKCcmJylcbiAgICAgIGNvbnN0IHVybCA9IHF1ZXJ5ID8gYCR7YmFzZVVybH0vdmFsdWVzPyR7cXVlcnl9YCA6IGAke2Jhc2VVcmx9L3ZhbHVlc2BcblxuICAgICAgY29uc3Qgd2F0Y2hlciA9IGNhY2hlLndhdGNoKClcbiAgICAgIGNvbnN0IFtlcnJvciwgcmVzcG9uc2VdID0gYXdhaXQgd3JhcFNpZ25lZEZldGNoPEdldFZhbHVlc1Jlc3VsdD4oeyB1cmwgfSlcbiAgICAgIHdhdGNoZXIuc3RvcCgpXG5cbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgc3RvcmFnZSB2YWx1ZXM6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBkYXRhID0gcmVzcG9uc2U/LmRhdGFcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgc3RvcmFnZSB2YWx1ZXM6IHJlc3BvbnNlIGNhcnJpZWQgbm8gZGF0YSBhcnJheScpXG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5zb21lKChlbnRyeSkgPT4gdHlwZW9mIGVudHJ5Py5rZXkgIT09ICdzdHJpbmcnIHx8IGVudHJ5LnZhbHVlID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGdldCBzdG9yYWdlIHZhbHVlczogcmVzcG9uc2UgY2FycmllZCBhIG1hbGZvcm1lZCBlbnRyeScpXG4gICAgICB9XG5cbiAgICAgIC8vIFNlZWQgdGhlIHBlci1rZXkgY2FjaGUgc28gc3Vic2VxdWVudCBnZXQoKS9zZXQoKSBvbiByZXR1cm5lZCBrZXlzIGNhblxuICAgICAgLy8gc2tpcCB0aGUgbmV0d29yay4gT25seSBrZXlzIHdpdGggbm8gbGl2ZSBlbnRyeSBhbmQgbm8gcGVuZGluZyB3cml0ZVxuICAgICAgLy8gYXJlIHNlZWRlZDogZXhpc3RpbmcgcGVyLWtleSBzdGF0ZSBjb21lcyBmcm9tIGEgY29uZmlybWVkIG9wZXJhdGlvblxuICAgICAgLy8gdGhhdCB0aGlzIHBhZ2Ugc25hcHNob3Qg4oCUIHdob3NlIHJlcXVlc3Qgc3RhcnRlZCBlYXJsaWVyIOKAlCBtdXN0IG5vdFxuICAgICAgLy8gY2xvYmJlciB3aXRoIHN0YWxlIGRhdGEuIEFic2VuY2UgaXMgbmV2ZXIgc2VlZGVkIChwcmVmaXgvcGFnaW5hdGlvblxuICAgICAgLy8gbWFrZSBpdCBub24tYXV0aG9yaXRhdGl2ZSkuIEEgcGFnZSBsYXJnZXIgdGhhbiBjYWNoZU1heEVudHJpZXMgY2h1cm5zXG4gICAgICAvLyB0aGUgY2FjaGU7IGVudHJpZXMgcmVwb3B1bGF0ZSBsYXppbHkuXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGRhdGEpIHtcbiAgICAgICAgaWYgKHdhdGNoZXIubXV0YXRlZChlbnRyeS5rZXkpIHx8IHdyaXRlcy5pc1BlbmRpbmcoZW50cnkua2V5KSB8fCBpbmZsaWdodEdldHMuaGFzKGVudHJ5LmtleSkpIGNvbnRpbnVlXG4gICAgICAgIGlmIChjYWNoZS5nZXQoZW50cnkua2V5KSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY2FjaGUuc2V0KGVudHJ5LmtleSwgeyBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHZhbHVlOiBlbnRyeS52YWx1ZSB9KSB9KVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcXVlc3RlZE9mZnNldCA9IG9mZnNldCA/PyAwXG4gICAgICBjb25zdCBwYWdpbmF0aW9uID0ge1xuICAgICAgICBvZmZzZXQ6IHJlc3BvbnNlIS5wYWdpbmF0aW9uPy5vZmZzZXQgPz8gcmVxdWVzdGVkT2Zmc2V0LFxuICAgICAgICB0b3RhbDogcmVzcG9uc2UhLnBhZ2luYXRpb24/LnRvdGFsID8/IGRhdGEubGVuZ3RoXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IGRhdGEsIHBhZ2luYXRpb24gfVxuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const LONE_SURROGATE = /[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
|
|
2
|
+
const UNSTORABLE_TEXT = /\u0000/;
|
|
3
|
+
const MAX_KEY_LENGTH = 255;
|
|
4
|
+
/**
|
|
5
|
+
* JSON.stringify always writes NUL as `\u0000` and an unpaired surrogate as a `\udXXX` escape (ES2019),
|
|
6
|
+
* while paired surrogates stay raw; an escaped backslash in front means the text is literal.
|
|
7
|
+
*/
|
|
8
|
+
const ESCAPED_UNSTORABLE_TEXT = /(?<!\\)(?:\\\\)*\\u(?:0000|d[89a-f][0-9a-f]{2})/i;
|
|
9
|
+
/** Raised from inside the replacer, so it is not mistaken for an engine error. */
|
|
10
|
+
class UnstorableValueError extends TypeError {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The `{ value }` PUT body. Rejects, at any depth, what JSON would drop or change: functions,
|
|
14
|
+
* symbols, non-finite numbers, `undefined` array elements and holes, built-ins with no JSON form
|
|
15
|
+
* (Map, Set, typed arrays, RegExp, Error, ...), and text the service cannot store. An `undefined`
|
|
16
|
+
* object property is dropped, as it reads back the same.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export function serializeStorageValue(value, callSite) {
|
|
20
|
+
const body = stringify(value, callSite, fastReason);
|
|
21
|
+
// Text is checked once on the output; only a rejection pays for locating the offending item.
|
|
22
|
+
if (ESCAPED_UNSTORABLE_TEXT.test(body)) {
|
|
23
|
+
stringify(value, callSite, unstorable);
|
|
24
|
+
throw new TypeError(`${callSite}: value must not contain an unpaired surrogate or a NUL character.`);
|
|
25
|
+
}
|
|
26
|
+
if (body === '{}') {
|
|
27
|
+
throw new TypeError(`${callSite}: value must be JSON-serializable. Use delete() to remove a key.`);
|
|
28
|
+
}
|
|
29
|
+
return body;
|
|
30
|
+
}
|
|
31
|
+
function stringify(value, callSite, reason) {
|
|
32
|
+
const envelope = { value };
|
|
33
|
+
try {
|
|
34
|
+
return JSON.stringify(envelope, function (property, item) {
|
|
35
|
+
const why = reason(this, property, item);
|
|
36
|
+
if (why) {
|
|
37
|
+
const where = this === envelope ? 'the value' : `"${property}"`;
|
|
38
|
+
throw new UnstorableValueError(`${callSite}: value must be JSON-serializable, but ${where} ${why}. Use delete() to remove a key.`);
|
|
39
|
+
}
|
|
40
|
+
return item;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (error instanceof UnstorableValueError)
|
|
45
|
+
throw error;
|
|
46
|
+
const cause = error instanceof Error ? error.message.split('\n')[0] : String(error);
|
|
47
|
+
throw new TypeError(`${callSite}: value must be JSON-serializable (${cause}). Use delete() to remove a key.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Everything but the text checks, with plain objects and arrays skipping the built-in check. */
|
|
51
|
+
function fastReason(holder, property, item) {
|
|
52
|
+
switch (typeof item) {
|
|
53
|
+
case 'function':
|
|
54
|
+
case 'symbol':
|
|
55
|
+
return `is a ${typeof item}`;
|
|
56
|
+
case 'number':
|
|
57
|
+
return Number.isFinite(item) ? undefined : `is the non-finite number ${item}`;
|
|
58
|
+
case 'undefined':
|
|
59
|
+
if (Array.isArray(holder))
|
|
60
|
+
return 'is undefined or a hole in an array';
|
|
61
|
+
return holder[property] !== undefined ? 'has a toJSON() that returns undefined' : undefined;
|
|
62
|
+
case 'object': {
|
|
63
|
+
if (item === null || Array.isArray(item))
|
|
64
|
+
return undefined;
|
|
65
|
+
const prototype = Object.getPrototypeOf(item);
|
|
66
|
+
return prototype === Object.prototype || prototype === null ? undefined : builtInReason(item);
|
|
67
|
+
}
|
|
68
|
+
default:
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Every check, per item: used to name the item a text rejection comes from. */
|
|
73
|
+
function unstorable(holder, property, item) {
|
|
74
|
+
const fast = fastReason(holder, property, item);
|
|
75
|
+
if (fast)
|
|
76
|
+
return fast;
|
|
77
|
+
if (typeof item === 'string' && (LONE_SURROGATE.test(item) || UNSTORABLE_TEXT.test(item))) {
|
|
78
|
+
return 'contains an unpaired surrogate or a NUL character';
|
|
79
|
+
}
|
|
80
|
+
if (!Array.isArray(holder) && (LONE_SURROGATE.test(property) || UNSTORABLE_TEXT.test(property))) {
|
|
81
|
+
return 'is a key with an unpaired surrogate or a NUL character';
|
|
82
|
+
}
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
function builtInReason(item) {
|
|
86
|
+
const builtIn = builtInName(item);
|
|
87
|
+
return builtIn ? `is ${/^[AEIO]/.test(builtIn) ? 'an' : 'a'} ${builtIn}, which has no JSON form` : undefined;
|
|
88
|
+
}
|
|
89
|
+
function builtInName(item) {
|
|
90
|
+
if (item === null || typeof item !== 'object')
|
|
91
|
+
return undefined;
|
|
92
|
+
if (item instanceof Map)
|
|
93
|
+
return 'Map';
|
|
94
|
+
if (item instanceof Set)
|
|
95
|
+
return 'Set';
|
|
96
|
+
if (item instanceof WeakMap)
|
|
97
|
+
return 'WeakMap';
|
|
98
|
+
if (item instanceof WeakSet)
|
|
99
|
+
return 'WeakSet';
|
|
100
|
+
if (item instanceof RegExp)
|
|
101
|
+
return 'RegExp';
|
|
102
|
+
if (item instanceof Error)
|
|
103
|
+
return 'Error';
|
|
104
|
+
if (item instanceof Promise)
|
|
105
|
+
return 'Promise';
|
|
106
|
+
if (item instanceof ArrayBuffer)
|
|
107
|
+
return 'ArrayBuffer';
|
|
108
|
+
if (ArrayBuffer.isView(item))
|
|
109
|
+
return item.constructor?.name ?? 'typed array';
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Keys and player addresses go into the request path, where `.`, `..` and an empty segment are
|
|
114
|
+
* resolved away by URL parsing, so they would address a different resource.
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
export function assertStorageKey(key, callSite) {
|
|
118
|
+
if (typeof key !== 'string' || key === '' || key === '.' || key === '..') {
|
|
119
|
+
throw new TypeError(`${callSite}: key must be a non-empty string other than "." and "..".`);
|
|
120
|
+
}
|
|
121
|
+
if (LONE_SURROGATE.test(key) || UNSTORABLE_TEXT.test(key)) {
|
|
122
|
+
throw new TypeError(`${callSite}: key must not contain an unpaired surrogate or a NUL character.`);
|
|
123
|
+
}
|
|
124
|
+
// Counted in characters, as the service counts them.
|
|
125
|
+
if ([...key].length > MAX_KEY_LENGTH) {
|
|
126
|
+
throw new TypeError(`${callSite}: key must be at most ${MAX_KEY_LENGTH} characters.`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** @internal */
|
|
130
|
+
export function assertPlayerAddress(address, callSite) {
|
|
131
|
+
if (typeof address !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(address)) {
|
|
132
|
+
throw new TypeError(`${callSite}: address must be a 0x-prefixed 20-byte hex address.`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXplLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZlci9zdG9yYWdlL3NlcmlhbGl6ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLGNBQWMsR0FBRyx3RUFBd0UsQ0FBQTtBQUMvRixNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUE7QUFDaEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFBO0FBRTFCOzs7R0FHRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsa0RBQWtELENBQUE7QUFFbEYsa0ZBQWtGO0FBQ2xGLE1BQU0sb0JBQXFCLFNBQVEsU0FBUztDQUFHO0FBSS9DOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFjLEVBQUUsUUFBZ0I7SUFDcEUsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDbkQsNkZBQTZGO0lBQzdGLElBQUksdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ3RDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFBO1FBQ3RDLE1BQU0sSUFBSSxTQUFTLENBQUMsR0FBRyxRQUFRLG9FQUFvRSxDQUFDLENBQUE7S0FDckc7SUFDRCxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUU7UUFDakIsTUFBTSxJQUFJLFNBQVMsQ0FBQyxHQUFHLFFBQVEsa0VBQWtFLENBQUMsQ0FBQTtLQUNuRztJQUNELE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEtBQWMsRUFBRSxRQUFnQixFQUFFLE1BQWM7SUFDakUsTUFBTSxRQUFRLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQTtJQUMxQixJQUFJO1FBQ0YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxVQUF5QyxRQUFRLEVBQUUsSUFBSTtZQUNyRixNQUFNLEdB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QixDQUFDLEdBQVksRUFBRSxRQUFnQjtJQUM3RCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLElBQUksRUFBRTtRQUN4RSxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsUUFBUSwyREFBMkQsQ0FBQyxDQUFBO0tBQzVGO0lBQ0QsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDekQsTUFBTSxJQUFJLFNBQVMsQ0FBQyxHQUFHLFFBQVEsa0VBQWtFLENBQUMsQ0FBQTtLQUNuRztJQUNELHFEQUFxRDtJQUNyRCxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsY0FBYyxFQUFFO1FBQ3BDLE1BQU0sSUFBSSxTQUFTLENBQUMsR0FBRyxRQUFRLHlCQUF5QixjQUFjLGNBQWMsQ0FBQyxDQUFBO0tBQ3RGO0FBQ0gsQ0FBQztBQUVELGdCQUFnQjtBQUNoQixNQUFNLFVBQVUsbUJBQW1CLENBQUMsT0FBZ0IsRUFBRSxRQUFnQjtJQUNwRSxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN2RSxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsUUFBUSxzREFBc0QsQ0FBQyxDQUFBO0tBQ3ZGO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IExPTkVfU1VSUk9HQVRFID0gL1tcXHVkODAwLVxcdWRiZmZdKD8hW1xcdWRjMDAtXFx1ZGZmZl0pfCg/PCFbXFx1ZDgwMC1cXHVkYmZmXSlbXFx1ZGMwMC1cXHVkZmZmXS9cbmNvbnN0IFVOU1RPUkFCTEVfVEVYVCA9IC9cXHUwMDAwL1xuY29uc3QgTUFYX0tFWV9MRU5HVEggPSAyNTVcblxuLyoqXG4gKiBKU09OLnN0cmluZ2lmeSBhbHdheXMgd3JpdGVzIE5VTCBhcyBgXFx1MDAwMGAgYW5kIGFuIHVucGFpcmVkIHN1cnJvZ2F0ZSBhcyBhIGBcXHVkWFhYYCBlc2NhcGUgKEVTMjAxOSksXG4gKiB3aGlsZSBwYWlyZWQgc3Vycm9nYXRlcyBzdGF5IHJhdzsgYW4gZXNjYXBlZCBiYWNrc2xhc2ggaW4gZnJvbnQgbWVhbnMgdGhlIHRleHQgaXMgbGl0ZXJhbC5cbiAqL1xuY29uc3QgRVNDQVBFRF9VTlNUT1JBQkxFX1RFWFQgPSAvKD88IVxcXFwpKD86XFxcXFxcXFwpKlxcXFx1KD86MDAwMHxkWzg5YS1mXVswLTlhLWZdezJ9KS9pXG5cbi8qKiBSYWlzZWQgZnJvbSBpbnNpZGUgdGhlIHJlcGxhY2VyLCBzbyBpdCBpcyBub3QgbWlzdGFrZW4gZm9yIGFuIGVuZ2luZSBlcnJvci4gKi9cbmNsYXNzIFVuc3RvcmFibGVWYWx1ZUVycm9yIGV4dGVuZHMgVHlwZUVycm9yIHt9XG5cbnR5cGUgUmVhc29uID0gKGhvbGRlcjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIHByb3BlcnR5OiBzdHJpbmcsIGl0ZW06IHVua25vd24pID0+IHN0cmluZyB8IHVuZGVmaW5lZFxuXG4vKipcbiAqIFRoZSBgeyB2YWx1ZSB9YCBQVVQgYm9keS4gUmVqZWN0cywgYXQgYW55IGRlcHRoLCB3aGF0IEpTT04gd291bGQgZHJvcCBvciBjaGFuZ2U6IGZ1bmN0aW9ucyxcbiAqIHN5bWJvbHMsIG5vbi1maW5pdGUgbnVtYmVycywgYHVuZGVmaW5lZGAgYXJyYXkgZWxlbWVudHMgYW5kIGhvbGVzLCBidWlsdC1pbnMgd2l0aCBubyBKU09OIGZvcm1cbiAqIChNYXAsIFNldCwgdHlwZWQgYXJyYXlzLCBSZWdFeHAsIEVycm9yLCAuLi4pLCBhbmQgdGV4dCB0aGUgc2VydmljZSBjYW5ub3Qgc3RvcmUuIEFuIGB1bmRlZmluZWRgXG4gKiBvYmplY3QgcHJvcGVydHkgaXMgZHJvcHBlZCwgYXMgaXQgcmVhZHMgYmFjayB0aGUgc2FtZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplU3RvcmFnZVZhbHVlKHZhbHVlOiB1bmtub3duLCBjYWxsU2l0ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgYm9keSA9IHN0cmluZ2lmeSh2YWx1ZSwgY2FsbFNpdGUsIGZhc3RSZWFzb24pXG4gIC8vIFRleHQgaXMgY2hlY2tlZCBvbmNlIG9uIHRoZSBvdXRwdXQ7IG9ubHkgYSByZWplY3Rpb24gcGF5cyBmb3IgbG9jYXRpbmcgdGhlIG9mZmVuZGluZyBpdGVtLlxuICBpZiAoRVNDQVBFRF9VTlNUT1JBQkxFX1RFWFQudGVzdChib2R5KSkge1xuICAgIHN0cmluZ2lmeSh2YWx1ZSwgY2FsbFNpdGUsIHVuc3RvcmFibGUpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IHZhbHVlIG11c3Qgbm90IGNvbnRhaW4gYW4gdW5wYWlyZWQgc3Vycm9nYXRlIG9yIGEgTlVMIGNoYXJhY3Rlci5gKVxuICB9XG4gIGlmIChib2R5ID09PSAne30nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IHZhbHVlIG11c3QgYmUgSlNPTi1zZXJpYWxpemFibGUuIFVzZSBkZWxldGUoKSB0byByZW1vdmUgYSBrZXkuYClcbiAgfVxuICByZXR1cm4gYm9keVxufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnkodmFsdWU6IHVua25vd24sIGNhbGxTaXRlOiBzdHJpbmcsIHJlYXNvbjogUmVhc29uKTogc3RyaW5nIHtcbiAgY29uc3QgZW52ZWxvcGUgPSB7IHZhbHVlIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUsIGZ1bmN0aW9uICh0aGlzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgcHJvcGVydHksIGl0ZW0pIHtcbiAgICAgIGNvbnN0IHdoeSA9IHJlYXNvbih0aGlzLCBwcm9wZXJ0eSwgaXRlbSlcbiAgICAgIGlmICh3aHkpIHtcbiAgICAgICAgY29uc3Qgd2hlcmUgPSB0aGlzID09PSBlbnZlbG9wZSA/ICd0aGUgdmFsdWUnIDogYFwiJHtwcm9wZXJ0eX1cImBcbiAgICAgICAgdGhyb3cgbmV3IFVuc3RvcmFibGVWYWx1ZUVycm9yKFxuICAgICAgICAgIGAke2NhbGxTaXRlfTogdmFsdWUgbXVzdCBiZSBKU09OLXNlcmlhbGl6YWJsZSwgYnV0ICR7d2hlcmV9ICR7d2h5fS4gVXNlIGRlbGV0ZSgpIHRvIHJlbW92ZSBhIGtleS5gXG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVtXG4gICAgfSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBVbnN0b3JhYmxlVmFsdWVFcnJvcikgdGhyb3cgZXJyb3JcbiAgICBjb25zdCBjYXVzZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlLnNwbGl0KCdcXG4nKVswXSA6IFN0cmluZyhlcnJvcilcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NhbGxTaXRlfTogdmFsdWUgbXVzdCBiZSBKU09OLXNlcmlhbGl6YWJsZSAoJHtjYXVzZX0pLiBVc2UgZGVsZXRlKCkgdG8gcmVtb3ZlIGEga2V5LmApXG4gIH1cbn1cblxuLyoqIEV2ZXJ5dGhpbmcgYnV0IHRoZSB0ZXh0IGNoZWNrcywgd2l0aCBwbGFpbiBvYmplY3RzIGFuZCBhcnJheXMgc2tpcHBpbmcgdGhlIGJ1aWx0LWluIGNoZWNrLiAqL1xuZnVuY3Rpb24gZmFzdFJlYXNvbihob2xkZXI6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBwcm9wZXJ0eTogc3RyaW5nLCBpdGVtOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgc3dpdGNoICh0eXBlb2YgaXRlbSkge1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgICAgcmV0dXJuIGBpcyBhICR7dHlwZW9mIGl0ZW19YFxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKGl0ZW0pID8gdW5kZWZpbmVkIDogYGlzIHRoZSBub24tZmluaXRlIG51bWJlciAke2l0ZW19YFxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShob2xkZXIpKSByZXR1cm4gJ2lzIHVuZGVmaW5lZCBvciBhIGhvbGUgaW4gYW4gYXJyYXknXG4gICAgICByZXR1cm4gaG9sZGVyW3Byb3BlcnR5XSAhPT0gdW5kZWZpbmVkID8gJ2hhcyBhIHRvSlNPTigpIHRoYXQgcmV0dXJucyB1bmRlZmluZWQnIDogdW5kZWZpbmVkXG4gICAgY2FzZSAnb2JqZWN0Jzoge1xuICAgICAgaWYgKGl0ZW0gPT09IG51bGwgfHwgQXJyYXkuaXNBcnJheShpdGVtKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgY29uc3QgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGl0ZW0pXG4gICAgICByZXR1cm4gcHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlIHx8IHByb3RvdHlwZSA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJ1aWx0SW5SZWFzb24oaXRlbSlcbiAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxufVxuXG4vKiogRXZlcnkgY2hlY2ssIHBlciBpdGVtOiB1c2VkIHRvIG5hbWUgdGhlIGl0ZW0gYSB0ZXh0IHJlamVjdGlvbiBjb21lcyBmcm9tLiAqL1xuZnVuY3Rpb24gdW5zdG9yYWJsZShob2xkZXI6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBwcm9wZXJ0eTogc3RyaW5nLCBpdGVtOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZmFzdCA9IGZhc3RSZWFzb24oaG9sZGVyLCBwcm9wZXJ0eSwgaXRlbSlcbiAgaWYgKGZhc3QpIHJldHVybiBmYXN0XG4gIGlmICh0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycgJiYgKExPTkVfU1VSUk9HQVRFLnRlc3QoaXRlbSkgfHwgVU5TVE9SQUJMRV9URVhULnRlc3QoaXRlbSkpKSB7XG4gICAgcmV0dXJuICdjb250YWlucyBhbiB1bnBhaXJlZCBzdXJyb2dhdGUgb3IgYSBOVUwgY2hhcmFjdGVyJ1xuICB9XG4gIGlmICghQXJyYXkuaXNBcnJheShob2xkZXIpICYmIChMT05FX1NVUlJPR0FURS50ZXN0KHByb3BlcnR5KSB8fCBVTlNUT1JBQkxFX1RFWFQudGVzdChwcm9wZXJ0eSkpKSB7XG4gICAgcmV0dXJuICdpcyBhIGtleSB3aXRoIGFuIHVucGFpcmVkIHN1cnJvZ2F0ZSBvciBhIE5VTCBjaGFyYWN0ZXInXG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBidWlsdEluUmVhc29uKGl0ZW06IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBidWlsdEluID0gYnVpbHRJbk5hbWUoaXRlbSlcbiAgcmV0dXJuIGJ1aWx0SW4gPyBgaXMgJHsvXltBRUlPXS8udGVzdChidWlsdEluKSA/ICdhbicgOiAnYSd9ICR7YnVpbHRJbn0sIHdoaWNoIGhhcyBubyBKU09OIGZvcm1gIDogdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGJ1aWx0SW5OYW1lKGl0ZW06IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoaXRlbSA9PT0gbnVsbCB8fCB0eXBlb2YgaXRlbSAhPT0gJ29iamVjdCcpIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBNYXApIHJldHVybiAnTWFwJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFNldCkgcmV0dXJuICdTZXQnXG4gIGlmIChpdGVtIGluc3RhbmNlb2YgV2Vha01hcCkgcmV0dXJuICdXZWFrTWFwJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFdlYWtTZXQpIHJldHVybiAnV2Vha1NldCdcbiAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiAnUmVnRXhwJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIEVycm9yKSByZXR1cm4gJ0Vycm9yJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFByb21pc2UpIHJldHVybiAnUHJvbWlzZSdcbiAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgcmV0dXJuICdBcnJheUJ1ZmZlcidcbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhpdGVtKSkgcmV0dXJuIGl0ZW0uY29uc3RydWN0b3I/Lm5hbWUgPz8gJ3R5cGVkIGFycmF5J1xuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogS2V5cyBhbmQgcGxheWVyIGFkZHJlc3NlcyBnbyBpbnRvIHRoZSByZXF1ZXN0IHBhdGgsIHdoZXJlIGAuYCwgYC4uYCBhbmQgYW4gZW1wdHkgc2VnbWVudCBhcmVcbiAqIHJlc29sdmVkIGF3YXkgYnkgVVJMIHBhcnNpbmcsIHNvIHRoZXkgd291bGQgYWRkcmVzcyBhIGRpZmZlcmVudCByZXNvdXJjZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0U3RvcmFnZUtleShrZXk6IHVua25vd24sIGNhbGxTaXRlOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnIHx8IGtleSA9PT0gJycgfHwga2V5ID09PSAnLicgfHwga2V5ID09PSAnLi4nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IGtleSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZyBvdGhlciB0aGFuIFwiLlwiIGFuZCBcIi4uXCIuYClcbiAgfVxuICBpZiAoTE9ORV9TVVJST0dBVEUudGVzdChrZXkpIHx8IFVOU1RPUkFCTEVfVEVYVC50ZXN0KGtleSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NhbGxTaXRlfToga2V5IG11c3Qgbm90IGNvbnRhaW4gYW4gdW5wYWlyZWQgc3Vycm9nYXRlIG9yIGEgTlVMIGNoYXJhY3Rlci5gKVxuICB9XG4gIC8vIENvdW50ZWQgaW4gY2hhcmFjdGVycywgYXMgdGhlIHNlcnZpY2UgY291bnRzIHRoZW0uXG4gIGlmIChbLi4ua2V5XS5sZW5ndGggPiBNQVhfS0VZX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y2FsbFNpdGV9OiBrZXkgbXVzdCBiZSBhdCBtb3N0ICR7TUFYX0tFWV9MRU5HVEh9IGNoYXJhY3RlcnMuYClcbiAgfVxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UGxheWVyQWRkcmVzcyhhZGRyZXNzOiB1bmtub3duLCBjYWxsU2l0ZTogc3RyaW5nKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgYWRkcmVzcyAhPT0gJ3N0cmluZycgfHwgIS9eMHhbMC05YS1mQS1GXXs0MH0kLy50ZXN0KGFkZHJlc3MpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IGFkZHJlc3MgbXVzdCBiZSBhIDB4LXByZWZpeGVkIDIwLWJ5dGUgaGV4IGFkZHJlc3MuYClcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DEFAULT_STORAGE_CONFIG } from './constants';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the bounded value cache shared by a storage scope.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function createValueCache(config) {
|
|
7
|
+
const entries = new Map();
|
|
8
|
+
const watchers = new Set();
|
|
9
|
+
function noteMutation(key) {
|
|
10
|
+
for (const seen of watchers)
|
|
11
|
+
seen.add(key);
|
|
12
|
+
}
|
|
13
|
+
function insert(key, entry) {
|
|
14
|
+
noteMutation(key);
|
|
15
|
+
// Delete + re-insert moves refreshed keys to the end of the Map's
|
|
16
|
+
// insertion order, so eviction below drops the least-recently-written.
|
|
17
|
+
entries.delete(key);
|
|
18
|
+
entries.set(key, { ...entry, storedAt: Date.now() });
|
|
19
|
+
// Guard against misconfiguration: a negative bound would loop forever on
|
|
20
|
+
// an empty map, and a NaN bound would silently disable eviction.
|
|
21
|
+
const maxEntries = !Number.isNaN(config.cacheMaxEntries)
|
|
22
|
+
? Math.max(0, config.cacheMaxEntries)
|
|
23
|
+
: DEFAULT_STORAGE_CONFIG.cacheMaxEntries;
|
|
24
|
+
while (entries.size > maxEntries) {
|
|
25
|
+
entries.delete(entries.keys().next().value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
get(key) {
|
|
30
|
+
const entry = entries.get(key);
|
|
31
|
+
if (!entry)
|
|
32
|
+
return undefined;
|
|
33
|
+
// Guard against misconfiguration, mirroring cacheMaxEntries: a NaN
|
|
34
|
+
// bound would silently disable expiry (NaN comparisons are false).
|
|
35
|
+
// Negative values need no guard — they just expire everything.
|
|
36
|
+
const maxAgeMs = !Number.isNaN(config.cacheMaxAgeMs) ? config.cacheMaxAgeMs : DEFAULT_STORAGE_CONFIG.cacheMaxAgeMs;
|
|
37
|
+
// Lazy max-age expiry: storedAt is never refreshed on hits, so the age
|
|
38
|
+
// bounds the time since the last actual network confirmation.
|
|
39
|
+
if (Date.now() - entry.storedAt > maxAgeMs) {
|
|
40
|
+
entries.delete(key);
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return entry;
|
|
44
|
+
},
|
|
45
|
+
set(key, entry) {
|
|
46
|
+
insert(key, entry);
|
|
47
|
+
},
|
|
48
|
+
setAbsent(key) {
|
|
49
|
+
insert(key, { absent: true });
|
|
50
|
+
},
|
|
51
|
+
delete(key) {
|
|
52
|
+
noteMutation(key);
|
|
53
|
+
entries.delete(key);
|
|
54
|
+
},
|
|
55
|
+
watch() {
|
|
56
|
+
const seen = new Set();
|
|
57
|
+
watchers.add(seen);
|
|
58
|
+
return {
|
|
59
|
+
mutated: (key) => seen.has(key),
|
|
60
|
+
stop: () => {
|
|
61
|
+
watchers.delete(seen);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsdWUtY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmVyL3N0b3JhZ2UvdmFsdWUtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHNCQUFzQixFQUFzQixNQUFNLGFBQWEsQ0FBQTtBQTRDeEU7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE1BQTBCO0lBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUE2QyxDQUFBO0lBQ3BFLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFlLENBQUE7SUFFdkMsU0FBUyxZQUFZLENBQUMsR0FBVztRQUMvQixLQUFLLE1BQU0sSUFBSSxJQUFJLFFBQVE7WUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRCxTQUFTLE1BQU0sQ0FBQyxHQUFXLEVBQUUsS0FBaUI7UUFDNUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2pCLGtFQUFrRTtRQUNsRSx1RUFBdUU7UUFDdkUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRXBELHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUM7WUFDdEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxlQUFlLENBQUM7WUFDckMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQTtRQUUxQyxPQUFPLE9BQU8sQ0FBQyxJQUFJLEdBQUcsVUFBVSxFQUFFO1lBQ2hDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQU0sQ0FBQyxDQUFBO1NBQzdDO0lBQ0gsQ0FBQztJQUVELE9BQU87UUFDTCxHQUFHLENBQUMsR0FBVztZQUNiLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDOUIsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxTQUFTLENBQUE7WUFFNUIsbUVBQW1FO1lBQ25FLG1FQUFtRTtZQUNuRSwrREFBK0Q7WUFDL0QsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFBO1lBRWxILHVFQUF1RTtZQUN2RSw4REFBOEQ7WUFDOUQsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLFFBQVEsR0FBRyxRQUFRLEVBQUU7Z0JBQzFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ25CLE9BQU8sU0FBUyxDQUFBO2FBQ2pCO1lBRUQsT0FBTyxLQUFLLENBQUE7UUFDZCxDQUFDO1FBRUQsR0FBRyxDQUFDLEdBQVcsRUFBRSxLQUF1QjtZQUN0QyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFBO1FBQ3BCLENBQUM7UUFFRCxTQUFTLENBQUMsR0FBVztZQUNuQixNQUFNLENBQUMsR0FBRyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFDL0IsQ0FBQztRQUVELE1BQU0sQ0FBQyxHQUFXO1lBQ2hCLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNqQixPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3JCLENBQUM7UUFFRCxLQUFLO1lBQ0gsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQTtZQUM5QixRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ2xCLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLEdBQUcsRUFBRTtvQkFDVCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO2dCQUN2QixDQUFDO2FBQ0YsQ0FBQTtRQUNILENBQUM7S0FDRixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERFRkFVTFRfU1RPUkFHRV9DT05GSUcsIFN0b3JhZ2VDb25maWdTdGF0ZSB9IGZyb20gJy4vY29uc3RhbnRzJ1xuXG4vKipcbiAqIEEgY2FjaGVkIGZhY3QgYWJvdXQgYSBrZXkncyBzZXJ2ZXItc2lkZSBzdGF0ZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlRW50cnkge1xuICAvKipcbiAgICogU2VyaWFsaXplZCBgeyB2YWx1ZSB9YCBib2R5OyBhYnNlbnQgZm9yIG5lZ2F0aXZlIGVudHJpZXMuIFBhcnNlZCBwZXIgcmVhZFxuICAgKiBoaXQgc28gY2FsbGVycyBuZXZlciBzaGFyZSBvYmplY3QgcmVmZXJlbmNlcywgYW5kIGNvbXBhcmVkIHZlcmJhdGltIGZvclxuICAgKiB3cml0ZSBkZWR1cCAoZXhhY3QgZXF1YWxpdHkg4oCUIG5vIGhhc2gtY29sbGlzaW9uIHJpc2spLlxuICAgKi9cbiAgYm9keT86IHN0cmluZ1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBzZXJ2ZXIgY29uZmlybWVkIHRoZSBrZXkgZG9lcyBub3QgZXhpc3QgKEdFVCA0MDQgb3Igc3VjY2Vzc2Z1bCBERUxFVEUpLiAqL1xuICBhYnNlbnQ/OiBib29sZWFuXG59XG5cbi8qKlxuICogQm91bmRlZCwgbGF6aWx5LWV4cGlyaW5nIGNhY2hlIG9mIGtleSBzdGF0ZXMsIGJhY2tpbmcgYm90aCB3cml0ZSBkZWR1cFxuICogKHNraXAgc3RvcmFnZSB3cml0ZXMgd2hvc2UgdmFsdWUgaXMgYWxyZWFkeSBrbm93biB0byBiZSBzdG9yZWQpIGFuZCByZWFkXG4gKiBjYWNoaW5nIChzZXJ2ZSBnZXQoKSB3aXRob3V0IGEgbmV0d29yayByZXF1ZXN0IHdpdGhpbiB0aGUgVFRMKS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbHVlQ2FjaGUge1xuICAvKiogUmV0dXJucyB0aGUgZW50cnkgaWYgcHJlc2VudCBhbmQgZnJlc2g7IGxhemlseSBldmljdHMgZXhwaXJlZCBlbnRyaWVzLiAqL1xuICBnZXQoa2V5OiBzdHJpbmcpOiBDYWNoZUVudHJ5IHwgdW5kZWZpbmVkXG4gIC8qKiBTdG9yZXMgb3IgcmVmcmVzaGVzIGEga25vd24gdmFsdWUgKHNlcmlhbGl6ZWQgYm9keSk7IG92ZXJ3cml0ZXMgbmVnYXRpdmUgZW50cmllcy4gKi9cbiAgc2V0KGtleTogc3RyaW5nLCBlbnRyeTogeyBib2R5OiBzdHJpbmcgfSk6IHZvaWRcbiAgLyoqIFN0b3JlcyBhIGNvbmZpcm1lZC1hYnNlbnQgKG5lZ2F0aXZlKSBlbnRyeSwgcmVwbGFjaW5nIGFueSB2YWx1ZSBlbnRyeS4gKi9cbiAgc2V0QWJzZW50KGtleTogc3RyaW5nKTogdm9pZFxuICBkZWxldGUoa2V5OiBzdHJpbmcpOiB2b2lkXG4gIC8qKiBTdGFydHMgcmVjb3JkaW5nIG11dGF0ZWQga2V5cywgc28gYSByZWFkIGlzc3VlZCBlYXJsaWVyIGNhbiB0ZWxsIGl0cyBzbmFwc2hvdCB3ZW50IHN0YWxlLiAqL1xuICB3YXRjaCgpOiBDYWNoZVdhdGNoZXJcbn1cblxuLyoqXG4gKiBLZXlzIG11dGF0ZWQgc2luY2UgdGhlIHdhdGNoIHN0YXJ0ZWQuIEFsd2F5cyBzdG9wKCkgaXQsIG9yIGl0IGtlZXBzIGNvbGxlY3RpbmcuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWNoZVdhdGNoZXIge1xuICBtdXRhdGVkKGtleTogc3RyaW5nKTogYm9vbGVhblxuICBzdG9wKCk6IHZvaWRcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBib3VuZGVkIHZhbHVlIGNhY2hlIHNoYXJlZCBieSBhIHN0b3JhZ2Ugc2NvcGUuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVZhbHVlQ2FjaGUoY29uZmlnOiBTdG9yYWdlQ29uZmlnU3RhdGUpOiBWYWx1ZUNhY2hlIHtcbiAgY29uc3QgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBDYWNoZUVudHJ5ICYgeyBzdG9yZWRBdDogbnVtYmVyIH0+KClcbiAgY29uc3Qgd2F0Y2hlcnMgPSBuZXcgU2V0PFNldDxzdHJpbmc+PigpXG5cbiAgZnVuY3Rpb24gbm90ZU11dGF0aW9uKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBzZWVuIG9mIHdhdGNoZXJzKSBzZWVuLmFkZChrZXkpXG4gIH1cblxuICBmdW5jdGlvbiBpbnNlcnQoa2V5OiBzdHJpbmcsIGVudHJ5OiBDYWNoZUVudHJ5KTogdm9pZCB7XG4gICAgbm90ZU11dGF0aW9uKGtleSlcbiAgICAvLyBEZWxldGUgKyByZS1pbnNlcnQgbW92ZXMgcmVmcmVzaGVkIGtleXMgdG8gdGhlIGVuZCBvZiB0aGUgTWFwJ3NcbiAgICAvLyBpbnNlcnRpb24gb3JkZXIsIHNvIGV2aWN0aW9uIGJlbG93IGRyb3BzIHRoZSBsZWFzdC1yZWNlbnRseS13cml0dGVuLlxuICAgIGVudHJpZXMuZGVsZXRlKGtleSlcbiAgICBlbnRyaWVzLnNldChrZXksIHsgLi4uZW50cnksIHN0b3JlZEF0OiBEYXRlLm5vdygpIH0pXG5cbiAgICAvLyBHdWFyZCBhZ2FpbnN0IG1pc2NvbmZpZ3VyYXRpb246IGEgbmVnYXRpdmUgYm91bmQgd291bGQgbG9vcCBmb3JldmVyIG9uXG4gICAgLy8gYW4gZW1wdHkgbWFwLCBhbmQgYSBOYU4gYm91bmQgd291bGQgc2lsZW50bHkgZGlzYWJsZSBldmljdGlvbi5cbiAgICBjb25zdCBtYXhFbnRyaWVzID0gIU51bWJlci5pc05hTihjb25maWcuY2FjaGVNYXhFbnRyaWVzKVxuICAgICAgPyBNYXRoLm1heCgwLCBjb25maWcuY2FjaGVNYXhFbnRyaWVzKVxuICAgICAgOiBERUZBVUxUX1NUT1JBR0VfQ09ORklHLmNhY2hlTWF4RW50cmllc1xuXG4gICAgd2hpbGUgKGVudHJpZXMuc2l6ZSA+IG1heEVudHJpZXMpIHtcbiAgICAgIGVudHJpZXMuZGVsZXRlKGVudHJpZXMua2V5cygpLm5leHQoKS52YWx1ZSEpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBnZXQoa2V5OiBzdHJpbmcpOiBDYWNoZUVudHJ5IHwgdW5kZWZpbmVkIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gZW50cmllcy5nZXQoa2V5KVxuICAgICAgaWYgKCFlbnRyeSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgICAvLyBHdWFyZCBhZ2FpbnN0IG1pc2NvbmZpZ3VyYXRpb24sIG1pcnJvcmluZyBjYWNoZU1heEVudHJpZXM6IGEgTmFOXG4gICAgICAvLyBib3VuZCB3b3VsZCBzaWxlbnRseSBkaXNhYmxlIGV4cGlyeSAoTmFOIGNvbXBhcmlzb25zIGFyZSBmYWxzZSkuXG4gICAgICAvLyBOZWdhdGl2ZSB2YWx1ZXMgbmVlZCBubyBndWFyZCDigJQgdGhleSBqdXN0IGV4cGlyZSBldmVyeXRoaW5nLlxuICAgICAgY29uc3QgbWF4QWdlTXMgPSAhTnVtYmVyLmlzTmFOKGNvbmZpZy5jYWNoZU1heEFnZU1zKSA/IGNvbmZpZy5jYWNoZU1heEFnZU1zIDogREVGQVVMVF9TVE9SQUdFX0NPTkZJRy5jYWNoZU1heEFnZU1zXG5cbiAgICAgIC8vIExhenkgbWF4LWFnZSBleHBpcnk6IHN0b3JlZEF0IGlzIG5ldmVyIHJlZnJlc2hlZCBvbiBoaXRzLCBzbyB0aGUgYWdlXG4gICAgICAvLyBib3VuZHMgdGhlIHRpbWUgc2luY2UgdGhlIGxhc3QgYWN0dWFsIG5ldHdvcmsgY29uZmlybWF0aW9uLlxuICAgICAgaWYgKERhdGUubm93KCkgLSBlbnRyeS5zdG9yZWRBdCA+IG1heEFnZU1zKSB7XG4gICAgICAgIGVudHJpZXMuZGVsZXRlKGtleSlcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZW50cnlcbiAgICB9LFxuXG4gICAgc2V0KGtleTogc3RyaW5nLCBlbnRyeTogeyBib2R5OiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgaW5zZXJ0KGtleSwgZW50cnkpXG4gICAgfSxcblxuICAgIHNldEFic2VudChrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgICAgaW5zZXJ0KGtleSwgeyBhYnNlbnQ6IHRydWUgfSlcbiAgICB9LFxuXG4gICAgZGVsZXRlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgICBub3RlTXV0YXRpb24oa2V5KVxuICAgICAgZW50cmllcy5kZWxldGUoa2V5KVxuICAgIH0sXG5cbiAgICB3YXRjaCgpOiBDYWNoZVdhdGNoZXIge1xuICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gICAgICB3YXRjaGVycy5hZGQoc2VlbilcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG11dGF0ZWQ6IChrZXk6IHN0cmluZykgPT4gc2Vlbi5oYXMoa2V5KSxcbiAgICAgICAgc3RvcDogKCkgPT4ge1xuICAgICAgICAgIHdhdGNoZXJzLmRlbGV0ZShzZWVuKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|