@amazon/vinyl-observable 1.0.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/dist/index.cjs ADDED
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, { get: all[name], enumerable: true });
23
+ };
24
+ var __copyProps = (to, from, except, desc) => {
25
+ if (from && typeof from === "object" || typeof from === "function") {
26
+ for (let key of __getOwnPropNames(from))
27
+ if (!__hasOwnProp.call(to, key) && key !== except)
28
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
29
+ }
30
+ return to;
31
+ };
32
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
34
+
35
+ // src/index.ts
36
+ var index_exports = {};
37
+ __export(index_exports, {
38
+ ExternalMutableValue: () => ExternalMutableValue,
39
+ MutableValueImpl: () => MutableValueImpl,
40
+ asData: () => asData,
41
+ combineData: () => combineData,
42
+ data: () => data,
43
+ externalData: () => externalData,
44
+ isObservableValue: () => isObservableValue
45
+ });
46
+ module.exports = __toCommonJS(index_exports);
47
+
48
+ // src/observable/observableValue.ts
49
+ var import_vinyl_util = require("@amazon/vinyl-util");
50
+ var MutableValueBase = class {
51
+ getValue() {
52
+ return this.value;
53
+ }
54
+ setValue(value) {
55
+ this.value = value;
56
+ }
57
+ map(transform, setData) {
58
+ return new SubDataController(
59
+ this,
60
+ transform,
61
+ setData != null ? setData : throwSaveNotProvidedError
62
+ );
63
+ }
64
+ pick(prop) {
65
+ return new SubDataController(
66
+ this,
67
+ (value) => {
68
+ return value == null ? void 0 : value[prop];
69
+ },
70
+ (subValue) => {
71
+ const current = this.value;
72
+ if (current == null) return current;
73
+ const newValue = __spreadValues({}, current);
74
+ newValue[prop] = subValue;
75
+ return newValue;
76
+ }
77
+ );
78
+ }
79
+ };
80
+ var MutableValueImpl = class extends MutableValueBase {
81
+ constructor(currentValue) {
82
+ super();
83
+ this.currentValue = currentValue;
84
+ __publicField(this, "_disposed", false);
85
+ __publicField(this, "currentIndex", -1);
86
+ __publicField(this, "n", 0);
87
+ __publicField(this, "callbacks", []);
88
+ __publicField(this, "_changeId", 0);
89
+ }
90
+ get changeId() {
91
+ return this._changeId;
92
+ }
93
+ hasAnyListeners() {
94
+ return this.callbacks.length > 0;
95
+ }
96
+ onData(callback) {
97
+ if (this._disposed) throw new import_vinyl_util.DisposedError();
98
+ this.callbacks.push(callback);
99
+ callback(this.currentValue, void 0);
100
+ return () => {
101
+ const index = this.callbacks.indexOf(callback);
102
+ if (index !== -1) {
103
+ this.callbacks.splice(index, 1);
104
+ if (index <= this.currentIndex) this.currentIndex--;
105
+ this.n--;
106
+ }
107
+ };
108
+ }
109
+ get value() {
110
+ return this.currentValue;
111
+ }
112
+ set value(value) {
113
+ if (this.currentIndex !== -1) {
114
+ throw new Error("data cannot be set from onData callback");
115
+ }
116
+ if (this._disposed) throw new import_vinyl_util.DisposedError();
117
+ const previousValue = this.currentValue;
118
+ if (value === previousValue) return;
119
+ this.currentValue = value;
120
+ this.notify(value, previousValue);
121
+ }
122
+ invalidate() {
123
+ this.notify(this.currentValue, this.currentValue);
124
+ }
125
+ get disposed() {
126
+ return this._disposed;
127
+ }
128
+ dispose() {
129
+ this._disposed = true;
130
+ this.callbacks.length = 0;
131
+ }
132
+ notify(value, previousValue) {
133
+ this._changeId++;
134
+ this.n = this.callbacks.length;
135
+ try {
136
+ while (this.currentIndex < this.n - 1) {
137
+ this.callbacks[++this.currentIndex](value, previousValue);
138
+ }
139
+ } finally {
140
+ this.currentIndex = -1;
141
+ }
142
+ }
143
+ };
144
+ var SubDataController = class extends MutableValueBase {
145
+ constructor(source, getter, setter) {
146
+ super();
147
+ this.source = source;
148
+ this.getter = getter;
149
+ this.setter = setter;
150
+ __publicField(this, "needsValidation", false);
151
+ __publicField(this, "cachedChangeId", -1);
152
+ __publicField(this, "cachedValue");
153
+ }
154
+ get changeId() {
155
+ return this.source.changeId;
156
+ }
157
+ getTransformed() {
158
+ const id = this.source.changeId;
159
+ if (this.cachedChangeId === id) return this.cachedValue;
160
+ const value = this.getter(this.source.value);
161
+ this.cachedChangeId = id;
162
+ this.cachedValue = value;
163
+ return value;
164
+ }
165
+ get value() {
166
+ return this.getTransformed();
167
+ }
168
+ set value(value) {
169
+ this.source.value = this.setter(value, this.source.value);
170
+ }
171
+ onData(callback) {
172
+ let previous;
173
+ let firstCall = true;
174
+ return this.source.onData(() => {
175
+ const newValue = this.getTransformed();
176
+ if (firstCall || this.needsValidation || newValue !== previous) {
177
+ callback(newValue, previous);
178
+ firstCall = false;
179
+ previous = newValue;
180
+ }
181
+ });
182
+ }
183
+ invalidate() {
184
+ this.needsValidation = true;
185
+ this.source.invalidate();
186
+ this.needsValidation = false;
187
+ }
188
+ };
189
+ function isObservableValue(value) {
190
+ if (value == null) return false;
191
+ return typeof value === "object" && "onData" in value && typeof value.onData === "function";
192
+ }
193
+ function data(value) {
194
+ return new MutableValueImpl(value);
195
+ }
196
+ function asData(value) {
197
+ return isObservableValue(value) ? value : data(value);
198
+ }
199
+ function throwSaveNotProvidedError() {
200
+ throw new Error("data cannot be set, a `setData` function must be provided");
201
+ }
202
+ var ExternalMutableValue = class extends MutableValueBase {
203
+ constructor(currentValue, onDataRequested) {
204
+ super();
205
+ this.onDataRequested = onDataRequested;
206
+ __publicField(this, "_data");
207
+ __publicField(this, "externalDataSub", null);
208
+ this._data = data(currentValue);
209
+ }
210
+ get value() {
211
+ return this._data.value;
212
+ }
213
+ get changeId() {
214
+ return this._data.changeId;
215
+ }
216
+ set value(_value) {
217
+ throw new Error("set value not supported");
218
+ }
219
+ onData(callback) {
220
+ if (!this._data.hasAnyListeners()) {
221
+ this.externalDataSub = this.onDataRequested((value) => {
222
+ this._data.value = value;
223
+ });
224
+ }
225
+ const sub = this._data.onData(callback);
226
+ return () => {
227
+ var _a;
228
+ sub();
229
+ if (!this._data.hasAnyListeners()) {
230
+ (_a = this.externalDataSub) == null ? void 0 : _a.call(this);
231
+ this.externalDataSub = null;
232
+ }
233
+ };
234
+ }
235
+ invalidate() {
236
+ throw new Error("invalidate not supported");
237
+ }
238
+ };
239
+ function externalData(initialValue, onDataRequested) {
240
+ return new ExternalMutableValue(initialValue, onDataRequested);
241
+ }
242
+
243
+ // src/observable/combineData.ts
244
+ function combineData(inputs) {
245
+ const keys = Object.keys(inputs);
246
+ const providers = {};
247
+ const current = {};
248
+ for (const key of keys) {
249
+ const provider = inputs[key];
250
+ providers[key] = provider;
251
+ current[key] = provider.value;
252
+ }
253
+ return externalData(current, (setData) => {
254
+ const subs = [];
255
+ for (const key of keys) {
256
+ const provider = providers[key];
257
+ let isFirst = true;
258
+ subs.push(
259
+ provider.onData((value) => {
260
+ if (isFirst) {
261
+ isFirst = false;
262
+ return;
263
+ }
264
+ current[key] = value;
265
+ setData(__spreadValues({}, current));
266
+ })
267
+ );
268
+ }
269
+ setData(current);
270
+ return () => {
271
+ for (const unsub of subs) unsub();
272
+ };
273
+ });
274
+ }
275
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/observable/observableValue.ts", "../src/observable/combineData.ts"],
4
+ "sourcesContent": ["/** Auto-generated from build scripts */\nexport * from './observable/observableValue'\nexport * from './observable/combineData'\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe, Unsubscribe } from '@amazon/vinyl-util'\nimport { DisposedError } from '@amazon/vinyl-util'\n\nexport interface ObservableValue<out T> {\n /**\n * Invokes a callback immediately and when data has changed.\n * @param callback\n */\n onData(callback: DataChangedCallback<T>): Unsubscribe\n\n /**\n * Creates a data provider transforming this data.\n */\n map<U>(transform: (value: T) => U): ObservableValue<U>\n\n /**\n * Returns a data provider for a property of T.\n */\n pick<K extends keyof NonNullable<T>>(prop: K): ObservableValue<Picked<T, K>>\n pick(prop: PropertyKey): ObservableValue<unknown>\n\n /**\n * The current value.\n */\n readonly value: T\n\n /**\n * Gets the current value.\n */\n getValue(): T\n\n /**\n * A monotonically increasing id that increments before each change notification.\n */\n readonly changeId: number\n}\n\nexport type MaybeObservableValue<T> = ObservableValue<T> | T\n\n/**\n * Given an ObservableValue<ValueType>, infers ValueType.\n */\nexport type InferObservableValueType<T extends ObservableValue<any>> =\n T extends ObservableValue<infer U> ? U : never\n\n/**\n * A mutable version of a data provider.\n */\nexport interface MutableValue<T> extends ObservableValue<T> {\n /**\n * The current value, may be set.\n * `onData` callbacks will be invoked if value is not exactly equal to\n * the current value.\n */\n value: T\n\n /**\n * Sets the current value.\n */\n setValue(value: T): void\n\n /**\n * Creates a readonly sub-controller for a transformed value.\n *\n * @param transform Applies a transformation to a single value using a provided function and returns the result.\n * The returned sub controller will use this as its value.\n */\n map<U>(transform: (value: T) => U): ObservableValue<U>\n\n /**\n * Creates a writable sub-controller for a transformed value.\n *\n * @param transform Applies a transformation to a single value using a provided function and returns the result.\n * The returned sub controller will use this as its value.\n * @param setData The reverse of transform; When the sub-controller's data is set, this will convert the\n * transformed value back to what can be saved on `this` controller.\n */\n map<U>(\n transform: (value: T) => U,\n setData: (transformed: U, original: T) => T\n ): MutableValue<U>\n\n /**\n * Returns a data controller for a property of T.\n */\n pick<K extends keyof NonNullable<T>>(prop: K): MutableValue<Picked<T, K>>\n pick(prop: PropertyKey): MutableValue<unknown>\n\n /**\n * Invokes subscribers, can be used to indicate a change without setting\n * a new value.\n */\n invalidate(): void\n}\n\nexport type DataChangedCallback<T> = (\n /**\n * The current value.\n */\n value: T,\n\n /**\n * The previous value, or undefined if this is the first time calling this callback.\n */\n previousValue: T | undefined\n) => void\n\nexport type Picked<T, K extends keyof NonNullable<T>> = T extends\n | undefined\n | null\n ? NonNullable<T>[K] | undefined\n : NonNullable<T>[K]\n\nabstract class MutableValueBase<T> implements MutableValue<T> {\n abstract value: T\n abstract readonly changeId: number\n\n getValue(): T {\n return this.value\n }\n\n setValue(value: T) {\n this.value = value\n }\n\n abstract onData(callback: DataChangedCallback<T>): Unsubscribe\n\n map<U>(\n transform: { (value: T): U },\n setData?: Maybe<(transformed: U, original: T) => T>\n ): MutableValue<U> {\n return new SubDataController<T, U>(\n this,\n transform,\n setData ?? throwSaveNotProvidedError\n )\n }\n\n pick<K extends keyof NonNullable<T>>(prop: K): MutableValue<Picked<T, K>> {\n return new SubDataController<T, Picked<T, K>>(\n this,\n (value: T): Picked<T, K> => {\n return (value == null ? undefined : value[prop]) as Picked<T, K>\n },\n (subValue) => {\n const current = this.value\n if (current == null) return current\n const newValue = { ...current }\n newValue[prop] = subValue!\n return newValue\n }\n )\n }\n\n abstract invalidate(): void\n}\n\nexport class MutableValueImpl<T> extends MutableValueBase<T> {\n private _disposed = false\n private currentIndex = -1\n private n = 0\n private readonly callbacks: DataChangedCallback<T>[] = []\n private _changeId = 0\n\n constructor(private currentValue: T) {\n super()\n }\n\n get changeId(): number {\n return this._changeId\n }\n\n hasAnyListeners(): boolean {\n return this.callbacks.length > 0\n }\n\n onData(callback: DataChangedCallback<T>): Unsubscribe {\n if (this._disposed) throw new DisposedError()\n this.callbacks.push(callback)\n callback(this.currentValue, undefined)\n return () => {\n // Remove the callback.\n const index = this.callbacks.indexOf(callback)\n if (index !== -1) {\n this.callbacks.splice(index, 1)\n if (index <= this.currentIndex) this.currentIndex--\n this.n--\n }\n }\n }\n\n get value(): T {\n return this.currentValue\n }\n\n set value(value: T) {\n if (this.currentIndex !== -1) {\n throw new Error('data cannot be set from onData callback')\n }\n if (this._disposed) throw new DisposedError()\n const previousValue = this.currentValue\n if (value === previousValue) return\n this.currentValue = value\n this.notify(value, previousValue)\n }\n\n invalidate() {\n this.notify(this.currentValue, this.currentValue)\n }\n\n get disposed(): boolean {\n return this._disposed\n }\n\n dispose() {\n this._disposed = true\n this.callbacks.length = 0\n }\n\n private notify(value: T, previousValue: T) {\n this._changeId++\n this.n = this.callbacks.length\n try {\n while (this.currentIndex < this.n - 1) {\n this.callbacks[++this.currentIndex](value, previousValue)\n }\n } finally {\n this.currentIndex = -1\n }\n }\n}\n\nclass SubDataController<FromType, T> extends MutableValueBase<T> {\n private needsValidation = false\n private cachedChangeId = -1\n private cachedValue: T | undefined\n\n constructor(\n private readonly source: MutableValue<FromType>,\n private readonly getter: (original: FromType) => T,\n private readonly setter: (\n transformed: T,\n original: FromType\n ) => FromType\n ) {\n super()\n }\n\n get changeId(): number {\n return this.source.changeId\n }\n\n private getTransformed(): T {\n const id = this.source.changeId\n if (this.cachedChangeId === id) return this.cachedValue!\n const value = this.getter(this.source.value)\n this.cachedChangeId = id\n this.cachedValue = value\n return value\n }\n\n get value(): T {\n return this.getTransformed()\n }\n\n set value(value: T) {\n this.source.value = this.setter(value, this.source.value)\n }\n\n onData(callback: DataChangedCallback<T>): Unsubscribe {\n let previous: T | undefined\n let firstCall = true\n return this.source.onData(() => {\n const newValue = this.getTransformed()\n if (firstCall || this.needsValidation || newValue !== previous) {\n callback(newValue, previous)\n firstCall = false\n previous = newValue\n }\n })\n }\n\n invalidate(): void {\n this.needsValidation = true\n this.source.invalidate()\n this.needsValidation = false\n }\n}\n\n/**\n * Returns true if the value is a ObservableValue.\n * @param value\n */\nexport function isObservableValue(value: any): value is ObservableValue<any> {\n if (value == null) return false\n return (\n typeof value === 'object' &&\n 'onData' in value &&\n typeof value.onData === 'function'\n )\n}\n\n/**\n * Creates a data provider.\n * @param value\n */\nexport function data<T>(value: T): MutableValueImpl<T> {\n return new MutableValueImpl<T>(value)\n}\n\n/**\n * If the value is a ObservableValue, returns the data provider as is. Otherwise, wraps the value in\n * provider.\n *\n * @param value\n */\nexport function asData<T>(value: MaybeObservableValue<T>): ObservableValue<T> {\n return isObservableValue(value) ? value : data(value)\n}\n\nfunction throwSaveNotProvidedError(): never {\n throw new Error('data cannot be set, a `setData` function must be provided')\n}\n\nexport type OnDataRequested<T> = (setData: (value: T) => void) => Unsubscribe\n\nexport class ExternalMutableValue<T> extends MutableValueBase<T> {\n private _data: MutableValueImpl<T>\n private externalDataSub: Unsubscribe | null = null\n\n constructor(\n currentValue: T,\n private readonly onDataRequested: OnDataRequested<T>\n ) {\n super()\n this._data = data(currentValue)\n }\n\n get value(): T {\n return this._data.value\n }\n\n get changeId(): number {\n return this._data.changeId\n }\n\n set value(_value: T) {\n throw new Error('set value not supported')\n }\n\n onData(callback: DataChangedCallback<T>): Unsubscribe {\n if (!this._data.hasAnyListeners()) {\n this.externalDataSub = this.onDataRequested((value: T): void => {\n this._data.value = value\n })\n }\n const sub = this._data.onData(callback)\n return () => {\n sub()\n if (!this._data.hasAnyListeners()) {\n this.externalDataSub?.()\n this.externalDataSub = null\n }\n }\n }\n\n invalidate(): void {\n throw new Error('invalidate not supported')\n }\n}\n\n/**\n * Creates a data provider that can observe an external event system when onData is called.\n *\n * @param initialValue\n * @param onDataRequested\n */\nexport function externalData<T>(\n initialValue: T,\n onDataRequested: (setData: (value: T) => void) => Unsubscribe\n): ObservableValue<T> {\n return new ExternalMutableValue(initialValue, onDataRequested)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { externalData, type ObservableValue } from './observableValue'\nimport type { ReadonlyRecord, Unsubscribe } from '@amazon/vinyl-util'\n\n/**\n * Combines a record of data providers into a single provider of a record of values.\n *\n * @param inputs A record of data providers.\n */\nexport function combineData<\n const T extends ReadonlyRecord<string, ObservableValue<unknown>>,\n>(\n inputs: T\n): ObservableValue<{\n readonly [K in keyof T]: T[K] extends ObservableValue<infer U> ? U : T[K]\n}> {\n type Output = {\n [K in keyof T]: T[K] extends ObservableValue<infer U> ? U : T[K]\n }\n\n const keys = Object.keys(inputs) as (keyof T)[]\n const providers: Record<keyof T, ObservableValue<any>> = {} as any\n const current: Partial<Output> = {}\n\n // Normalize all inputs to DataProviders and initialize current value\n for (const key of keys) {\n const provider = inputs[key]\n providers[key] = provider\n current[key] = provider.value as any\n }\n\n return externalData(current as Output, (setData) => {\n const subs: Unsubscribe[] = []\n\n for (const key of keys) {\n const provider = providers[key]\n let isFirst = true\n subs.push(\n provider.onData((value) => {\n if (isFirst) {\n isFirst = false\n return\n }\n current[key] = value\n setData({ ...current } as Output)\n })\n )\n }\n setData(current as Output)\n\n return () => {\n for (const unsub of subs) unsub()\n }\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/dist/index.js ADDED
@@ -0,0 +1,255 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
18
+
19
+ // src/observable/observableValue.ts
20
+ import { DisposedError } from "@amazon/vinyl-util";
21
+ var MutableValueBase = class {
22
+ getValue() {
23
+ return this.value;
24
+ }
25
+ setValue(value) {
26
+ this.value = value;
27
+ }
28
+ map(transform, setData) {
29
+ return new SubDataController(
30
+ this,
31
+ transform,
32
+ setData != null ? setData : throwSaveNotProvidedError
33
+ );
34
+ }
35
+ pick(prop) {
36
+ return new SubDataController(
37
+ this,
38
+ (value) => {
39
+ return value == null ? void 0 : value[prop];
40
+ },
41
+ (subValue) => {
42
+ const current = this.value;
43
+ if (current == null) return current;
44
+ const newValue = __spreadValues({}, current);
45
+ newValue[prop] = subValue;
46
+ return newValue;
47
+ }
48
+ );
49
+ }
50
+ };
51
+ var MutableValueImpl = class extends MutableValueBase {
52
+ constructor(currentValue) {
53
+ super();
54
+ this.currentValue = currentValue;
55
+ __publicField(this, "_disposed", false);
56
+ __publicField(this, "currentIndex", -1);
57
+ __publicField(this, "n", 0);
58
+ __publicField(this, "callbacks", []);
59
+ __publicField(this, "_changeId", 0);
60
+ }
61
+ get changeId() {
62
+ return this._changeId;
63
+ }
64
+ hasAnyListeners() {
65
+ return this.callbacks.length > 0;
66
+ }
67
+ onData(callback) {
68
+ if (this._disposed) throw new DisposedError();
69
+ this.callbacks.push(callback);
70
+ callback(this.currentValue, void 0);
71
+ return () => {
72
+ const index = this.callbacks.indexOf(callback);
73
+ if (index !== -1) {
74
+ this.callbacks.splice(index, 1);
75
+ if (index <= this.currentIndex) this.currentIndex--;
76
+ this.n--;
77
+ }
78
+ };
79
+ }
80
+ get value() {
81
+ return this.currentValue;
82
+ }
83
+ set value(value) {
84
+ if (this.currentIndex !== -1) {
85
+ throw new Error("data cannot be set from onData callback");
86
+ }
87
+ if (this._disposed) throw new DisposedError();
88
+ const previousValue = this.currentValue;
89
+ if (value === previousValue) return;
90
+ this.currentValue = value;
91
+ this.notify(value, previousValue);
92
+ }
93
+ invalidate() {
94
+ this.notify(this.currentValue, this.currentValue);
95
+ }
96
+ get disposed() {
97
+ return this._disposed;
98
+ }
99
+ dispose() {
100
+ this._disposed = true;
101
+ this.callbacks.length = 0;
102
+ }
103
+ notify(value, previousValue) {
104
+ this._changeId++;
105
+ this.n = this.callbacks.length;
106
+ try {
107
+ while (this.currentIndex < this.n - 1) {
108
+ this.callbacks[++this.currentIndex](value, previousValue);
109
+ }
110
+ } finally {
111
+ this.currentIndex = -1;
112
+ }
113
+ }
114
+ };
115
+ var SubDataController = class extends MutableValueBase {
116
+ constructor(source, getter, setter) {
117
+ super();
118
+ this.source = source;
119
+ this.getter = getter;
120
+ this.setter = setter;
121
+ __publicField(this, "needsValidation", false);
122
+ __publicField(this, "cachedChangeId", -1);
123
+ __publicField(this, "cachedValue");
124
+ }
125
+ get changeId() {
126
+ return this.source.changeId;
127
+ }
128
+ getTransformed() {
129
+ const id = this.source.changeId;
130
+ if (this.cachedChangeId === id) return this.cachedValue;
131
+ const value = this.getter(this.source.value);
132
+ this.cachedChangeId = id;
133
+ this.cachedValue = value;
134
+ return value;
135
+ }
136
+ get value() {
137
+ return this.getTransformed();
138
+ }
139
+ set value(value) {
140
+ this.source.value = this.setter(value, this.source.value);
141
+ }
142
+ onData(callback) {
143
+ let previous;
144
+ let firstCall = true;
145
+ return this.source.onData(() => {
146
+ const newValue = this.getTransformed();
147
+ if (firstCall || this.needsValidation || newValue !== previous) {
148
+ callback(newValue, previous);
149
+ firstCall = false;
150
+ previous = newValue;
151
+ }
152
+ });
153
+ }
154
+ invalidate() {
155
+ this.needsValidation = true;
156
+ this.source.invalidate();
157
+ this.needsValidation = false;
158
+ }
159
+ };
160
+ function isObservableValue(value) {
161
+ if (value == null) return false;
162
+ return typeof value === "object" && "onData" in value && typeof value.onData === "function";
163
+ }
164
+ function data(value) {
165
+ return new MutableValueImpl(value);
166
+ }
167
+ function asData(value) {
168
+ return isObservableValue(value) ? value : data(value);
169
+ }
170
+ function throwSaveNotProvidedError() {
171
+ throw new Error("data cannot be set, a `setData` function must be provided");
172
+ }
173
+ var ExternalMutableValue = class extends MutableValueBase {
174
+ constructor(currentValue, onDataRequested) {
175
+ super();
176
+ this.onDataRequested = onDataRequested;
177
+ __publicField(this, "_data");
178
+ __publicField(this, "externalDataSub", null);
179
+ this._data = data(currentValue);
180
+ }
181
+ get value() {
182
+ return this._data.value;
183
+ }
184
+ get changeId() {
185
+ return this._data.changeId;
186
+ }
187
+ set value(_value) {
188
+ throw new Error("set value not supported");
189
+ }
190
+ onData(callback) {
191
+ if (!this._data.hasAnyListeners()) {
192
+ this.externalDataSub = this.onDataRequested((value) => {
193
+ this._data.value = value;
194
+ });
195
+ }
196
+ const sub = this._data.onData(callback);
197
+ return () => {
198
+ var _a;
199
+ sub();
200
+ if (!this._data.hasAnyListeners()) {
201
+ (_a = this.externalDataSub) == null ? void 0 : _a.call(this);
202
+ this.externalDataSub = null;
203
+ }
204
+ };
205
+ }
206
+ invalidate() {
207
+ throw new Error("invalidate not supported");
208
+ }
209
+ };
210
+ function externalData(initialValue, onDataRequested) {
211
+ return new ExternalMutableValue(initialValue, onDataRequested);
212
+ }
213
+
214
+ // src/observable/combineData.ts
215
+ function combineData(inputs) {
216
+ const keys = Object.keys(inputs);
217
+ const providers = {};
218
+ const current = {};
219
+ for (const key of keys) {
220
+ const provider = inputs[key];
221
+ providers[key] = provider;
222
+ current[key] = provider.value;
223
+ }
224
+ return externalData(current, (setData) => {
225
+ const subs = [];
226
+ for (const key of keys) {
227
+ const provider = providers[key];
228
+ let isFirst = true;
229
+ subs.push(
230
+ provider.onData((value) => {
231
+ if (isFirst) {
232
+ isFirst = false;
233
+ return;
234
+ }
235
+ current[key] = value;
236
+ setData(__spreadValues({}, current));
237
+ })
238
+ );
239
+ }
240
+ setData(current);
241
+ return () => {
242
+ for (const unsub of subs) unsub();
243
+ };
244
+ });
245
+ }
246
+ export {
247
+ ExternalMutableValue,
248
+ MutableValueImpl,
249
+ asData,
250
+ combineData,
251
+ data,
252
+ externalData,
253
+ isObservableValue
254
+ };
255
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/observable/observableValue.ts", "../src/observable/combineData.ts"],
4
+ "sourcesContent": ["/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe, Unsubscribe } from '@amazon/vinyl-util'\nimport { DisposedError } from '@amazon/vinyl-util'\n\nexport interface ObservableValue<out T> {\n /**\n * Invokes a callback immediately and when data has changed.\n * @param callback\n */\n onData(callback: DataChangedCallback<T>): Unsubscribe\n\n /**\n * Creates a data provider transforming this data.\n */\n map<U>(transform: (value: T) => U): ObservableValue<U>\n\n /**\n * Returns a data provider for a property of T.\n */\n pick<K extends keyof NonNullable<T>>(prop: K): ObservableValue<Picked<T, K>>\n pick(prop: PropertyKey): ObservableValue<unknown>\n\n /**\n * The current value.\n */\n readonly value: T\n\n /**\n * Gets the current value.\n */\n getValue(): T\n\n /**\n * A monotonically increasing id that increments before each change notification.\n */\n readonly changeId: number\n}\n\nexport type MaybeObservableValue<T> = ObservableValue<T> | T\n\n/**\n * Given an ObservableValue<ValueType>, infers ValueType.\n */\nexport type InferObservableValueType<T extends ObservableValue<any>> =\n T extends ObservableValue<infer U> ? U : never\n\n/**\n * A mutable version of a data provider.\n */\nexport interface MutableValue<T> extends ObservableValue<T> {\n /**\n * The current value, may be set.\n * `onData` callbacks will be invoked if value is not exactly equal to\n * the current value.\n */\n value: T\n\n /**\n * Sets the current value.\n */\n setValue(value: T): void\n\n /**\n * Creates a readonly sub-controller for a transformed value.\n *\n * @param transform Applies a transformation to a single value using a provided function and returns the result.\n * The returned sub controller will use this as its value.\n */\n map<U>(transform: (value: T) => U): ObservableValue<U>\n\n /**\n * Creates a writable sub-controller for a transformed value.\n *\n * @param transform Applies a transformation to a single value using a provided function and returns the result.\n * The returned sub controller will use this as its value.\n * @param setData The reverse of transform; When the sub-controller's data is set, this will convert the\n * transformed value back to what can be saved on `this` controller.\n */\n map<U>(\n transform: (value: T) => U,\n setData: (transformed: U, original: T) => T\n ): MutableValue<U>\n\n /**\n * Returns a data controller for a property of T.\n */\n pick<K extends keyof NonNullable<T>>(prop: K): MutableValue<Picked<T, K>>\n pick(prop: PropertyKey): MutableValue<unknown>\n\n /**\n * Invokes subscribers, can be used to indicate a change without setting\n * a new value.\n */\n invalidate(): void\n}\n\nexport type DataChangedCallback<T> = (\n /**\n * The current value.\n */\n value: T,\n\n /**\n * The previous value, or undefined if this is the first time calling this callback.\n */\n previousValue: T | undefined\n) => void\n\nexport type Picked<T, K extends keyof NonNullable<T>> = T extends\n | undefined\n | null\n ? NonNullable<T>[K] | undefined\n : NonNullable<T>[K]\n\nabstract class MutableValueBase<T> implements MutableValue<T> {\n abstract value: T\n abstract readonly changeId: number\n\n getValue(): T {\n return this.value\n }\n\n setValue(value: T) {\n this.value = value\n }\n\n abstract onData(callback: DataChangedCallback<T>): Unsubscribe\n\n map<U>(\n transform: { (value: T): U },\n setData?: Maybe<(transformed: U, original: T) => T>\n ): MutableValue<U> {\n return new SubDataController<T, U>(\n this,\n transform,\n setData ?? throwSaveNotProvidedError\n )\n }\n\n pick<K extends keyof NonNullable<T>>(prop: K): MutableValue<Picked<T, K>> {\n return new SubDataController<T, Picked<T, K>>(\n this,\n (value: T): Picked<T, K> => {\n return (value == null ? undefined : value[prop]) as Picked<T, K>\n },\n (subValue) => {\n const current = this.value\n if (current == null) return current\n const newValue = { ...current }\n newValue[prop] = subValue!\n return newValue\n }\n )\n }\n\n abstract invalidate(): void\n}\n\nexport class MutableValueImpl<T> extends MutableValueBase<T> {\n private _disposed = false\n private currentIndex = -1\n private n = 0\n private readonly callbacks: DataChangedCallback<T>[] = []\n private _changeId = 0\n\n constructor(private currentValue: T) {\n super()\n }\n\n get changeId(): number {\n return this._changeId\n }\n\n hasAnyListeners(): boolean {\n return this.callbacks.length > 0\n }\n\n onData(callback: DataChangedCallback<T>): Unsubscribe {\n if (this._disposed) throw new DisposedError()\n this.callbacks.push(callback)\n callback(this.currentValue, undefined)\n return () => {\n // Remove the callback.\n const index = this.callbacks.indexOf(callback)\n if (index !== -1) {\n this.callbacks.splice(index, 1)\n if (index <= this.currentIndex) this.currentIndex--\n this.n--\n }\n }\n }\n\n get value(): T {\n return this.currentValue\n }\n\n set value(value: T) {\n if (this.currentIndex !== -1) {\n throw new Error('data cannot be set from onData callback')\n }\n if (this._disposed) throw new DisposedError()\n const previousValue = this.currentValue\n if (value === previousValue) return\n this.currentValue = value\n this.notify(value, previousValue)\n }\n\n invalidate() {\n this.notify(this.currentValue, this.currentValue)\n }\n\n get disposed(): boolean {\n return this._disposed\n }\n\n dispose() {\n this._disposed = true\n this.callbacks.length = 0\n }\n\n private notify(value: T, previousValue: T) {\n this._changeId++\n this.n = this.callbacks.length\n try {\n while (this.currentIndex < this.n - 1) {\n this.callbacks[++this.currentIndex](value, previousValue)\n }\n } finally {\n this.currentIndex = -1\n }\n }\n}\n\nclass SubDataController<FromType, T> extends MutableValueBase<T> {\n private needsValidation = false\n private cachedChangeId = -1\n private cachedValue: T | undefined\n\n constructor(\n private readonly source: MutableValue<FromType>,\n private readonly getter: (original: FromType) => T,\n private readonly setter: (\n transformed: T,\n original: FromType\n ) => FromType\n ) {\n super()\n }\n\n get changeId(): number {\n return this.source.changeId\n }\n\n private getTransformed(): T {\n const id = this.source.changeId\n if (this.cachedChangeId === id) return this.cachedValue!\n const value = this.getter(this.source.value)\n this.cachedChangeId = id\n this.cachedValue = value\n return value\n }\n\n get value(): T {\n return this.getTransformed()\n }\n\n set value(value: T) {\n this.source.value = this.setter(value, this.source.value)\n }\n\n onData(callback: DataChangedCallback<T>): Unsubscribe {\n let previous: T | undefined\n let firstCall = true\n return this.source.onData(() => {\n const newValue = this.getTransformed()\n if (firstCall || this.needsValidation || newValue !== previous) {\n callback(newValue, previous)\n firstCall = false\n previous = newValue\n }\n })\n }\n\n invalidate(): void {\n this.needsValidation = true\n this.source.invalidate()\n this.needsValidation = false\n }\n}\n\n/**\n * Returns true if the value is a ObservableValue.\n * @param value\n */\nexport function isObservableValue(value: any): value is ObservableValue<any> {\n if (value == null) return false\n return (\n typeof value === 'object' &&\n 'onData' in value &&\n typeof value.onData === 'function'\n )\n}\n\n/**\n * Creates a data provider.\n * @param value\n */\nexport function data<T>(value: T): MutableValueImpl<T> {\n return new MutableValueImpl<T>(value)\n}\n\n/**\n * If the value is a ObservableValue, returns the data provider as is. Otherwise, wraps the value in\n * provider.\n *\n * @param value\n */\nexport function asData<T>(value: MaybeObservableValue<T>): ObservableValue<T> {\n return isObservableValue(value) ? value : data(value)\n}\n\nfunction throwSaveNotProvidedError(): never {\n throw new Error('data cannot be set, a `setData` function must be provided')\n}\n\nexport type OnDataRequested<T> = (setData: (value: T) => void) => Unsubscribe\n\nexport class ExternalMutableValue<T> extends MutableValueBase<T> {\n private _data: MutableValueImpl<T>\n private externalDataSub: Unsubscribe | null = null\n\n constructor(\n currentValue: T,\n private readonly onDataRequested: OnDataRequested<T>\n ) {\n super()\n this._data = data(currentValue)\n }\n\n get value(): T {\n return this._data.value\n }\n\n get changeId(): number {\n return this._data.changeId\n }\n\n set value(_value: T) {\n throw new Error('set value not supported')\n }\n\n onData(callback: DataChangedCallback<T>): Unsubscribe {\n if (!this._data.hasAnyListeners()) {\n this.externalDataSub = this.onDataRequested((value: T): void => {\n this._data.value = value\n })\n }\n const sub = this._data.onData(callback)\n return () => {\n sub()\n if (!this._data.hasAnyListeners()) {\n this.externalDataSub?.()\n this.externalDataSub = null\n }\n }\n }\n\n invalidate(): void {\n throw new Error('invalidate not supported')\n }\n}\n\n/**\n * Creates a data provider that can observe an external event system when onData is called.\n *\n * @param initialValue\n * @param onDataRequested\n */\nexport function externalData<T>(\n initialValue: T,\n onDataRequested: (setData: (value: T) => void) => Unsubscribe\n): ObservableValue<T> {\n return new ExternalMutableValue(initialValue, onDataRequested)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { externalData, type ObservableValue } from './observableValue'\nimport type { ReadonlyRecord, Unsubscribe } from '@amazon/vinyl-util'\n\n/**\n * Combines a record of data providers into a single provider of a record of values.\n *\n * @param inputs A record of data providers.\n */\nexport function combineData<\n const T extends ReadonlyRecord<string, ObservableValue<unknown>>,\n>(\n inputs: T\n): ObservableValue<{\n readonly [K in keyof T]: T[K] extends ObservableValue<infer U> ? U : T[K]\n}> {\n type Output = {\n [K in keyof T]: T[K] extends ObservableValue<infer U> ? U : T[K]\n }\n\n const keys = Object.keys(inputs) as (keyof T)[]\n const providers: Record<keyof T, ObservableValue<any>> = {} as any\n const current: Partial<Output> = {}\n\n // Normalize all inputs to DataProviders and initialize current value\n for (const key of keys) {\n const provider = inputs[key]\n providers[key] = provider\n current[key] = provider.value as any\n }\n\n return externalData(current as Output, (setData) => {\n const subs: Unsubscribe[] = []\n\n for (const key of keys) {\n const provider = providers[key]\n let isFirst = true\n subs.push(\n provider.onData((value) => {\n if (isFirst) {\n isFirst = false\n return\n }\n current[key] = value\n setData({ ...current } as Output)\n })\n )\n }\n setData(current as Output)\n\n return () => {\n for (const unsub of subs) unsub()\n }\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,4 @@
1
+ /** Auto-generated from build scripts */
2
+ export * from './observable/observableValue';
3
+ export * from './observable/combineData';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA"}
@@ -0,0 +1,3 @@
1
+ /** Auto-generated from build scripts */
2
+ export * from './observable/observableValue';
3
+ export * from './observable/combineData';
@@ -0,0 +1,11 @@
1
+ import { type ObservableValue } from './observableValue';
2
+ import type { ReadonlyRecord } from '@amazon/vinyl-util';
3
+ /**
4
+ * Combines a record of data providers into a single provider of a record of values.
5
+ *
6
+ * @param inputs A record of data providers.
7
+ */
8
+ export declare function combineData<const T extends ReadonlyRecord<string, ObservableValue<unknown>>>(inputs: T): ObservableValue<{
9
+ readonly [K in keyof T]: T[K] extends ObservableValue<infer U> ? U : T[K];
10
+ }>;
11
+ //# sourceMappingURL=combineData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combineData.d.ts","sourceRoot":"","sources":["../../../../src/observable/combineData.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,oBAAoB,CAAA;AAErE;;;;GAIG;AACH,wBAAgB,WAAW,CACvB,KAAK,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,EAEhE,MAAM,EAAE,CAAC,GACV,eAAe,CAAC;IACf,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC5E,CAAC,CAuCD"}