@remote-ui/async-subscription
Advanced tools
Comparing version 1.1.0-alpha.0 to 2.0.0
@@ -6,8 +6,8 @@ "use strict"; | ||
}); | ||
exports.createAsyncSubscription = createAsyncSubscription; | ||
exports.createRemoteSubscribable = createRemoteSubscribable; | ||
var _rpc = require("@remote-ui/rpc"); | ||
function createAsyncSubscription(subscription) { | ||
var initial = subscription.getCurrentValue(); | ||
function createRemoteSubscribable(subscription) { | ||
var initial = subscription.current; | ||
return { | ||
@@ -18,3 +18,3 @@ initial: initial, | ||
var unsubscribe = subscription.subscribe(function () { | ||
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : subscription.getCurrentValue(); | ||
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : subscription.current; | ||
subscriber(value); | ||
@@ -28,5 +28,5 @@ }); | ||
return [teardown, subscription.getCurrentValue()]; | ||
return [teardown, subscription.current]; | ||
} | ||
}; | ||
} |
@@ -6,12 +6,12 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "makeStateful", { | ||
Object.defineProperty(exports, "makeStatefulSubscribable", { | ||
enumerable: true, | ||
get: function get() { | ||
return _stateful.makeStateful; | ||
return _stateful.makeStatefulSubscribable; | ||
} | ||
}); | ||
Object.defineProperty(exports, "createAsyncSubscription", { | ||
Object.defineProperty(exports, "createRemoteSubscribable", { | ||
enumerable: true, | ||
get: function get() { | ||
return _create.createAsyncSubscription; | ||
return _create.createRemoteSubscribable; | ||
} | ||
@@ -18,0 +18,0 @@ }); |
@@ -6,6 +6,10 @@ "use strict"; | ||
}); | ||
exports.makeStateful = makeStateful; | ||
exports.makeStatefulSubscribable = makeStatefulSubscribable; | ||
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); | ||
var _rpc = require("@remote-ui/rpc"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } | ||
@@ -25,3 +29,7 @@ | ||
function makeStateful(subscription) { | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
function makeStatefulSubscribable(subscription) { | ||
// We retain because it will automatically retain any functions we get from | ||
@@ -39,5 +47,6 @@ // calling functions on this object, which will automatically manage the memory | ||
return { | ||
getCurrentValue: function getCurrentValue() { | ||
get current() { | ||
return current; | ||
}, | ||
subscribe: function subscribe(subscriber) { | ||
@@ -49,12 +58,29 @@ subscribers.add(subscriber); | ||
}, | ||
stop: function stop() { | ||
listening = false; | ||
subscribers.clear(); | ||
return subscriptionResult.then(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 1), | ||
unsubscribe = _ref2[0]; | ||
destroy: function destroy() { | ||
return _asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
var _yield$subscriptionRe, _yield$subscriptionRe2, unsubscribe; | ||
unsubscribe(); | ||
(0, _rpc.release)(subscription); | ||
}); | ||
return _regenerator["default"].wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
listening = false; | ||
subscribers.clear(); | ||
_context.next = 4; | ||
return subscriptionResult; | ||
case 4: | ||
_yield$subscriptionRe = _context.sent; | ||
_yield$subscriptionRe2 = _slicedToArray(_yield$subscriptionRe, 1); | ||
unsubscribe = _yield$subscriptionRe2[0]; | ||
unsubscribe(); | ||
(0, _rpc.release)(subscription); | ||
case 9: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
}))(); | ||
} | ||
@@ -61,0 +87,0 @@ }; |
@@ -38,3 +38,3 @@ "use strict"; | ||
describe('createAsyncSubscription()', function () { | ||
describe('createRemoteSubscribable()', function () { | ||
beforeEach(function () { | ||
@@ -46,4 +46,4 @@ release.mockReset(); | ||
var initial = 123; | ||
var subscription = createSyncSubscription(initial); | ||
expect((0, _create.createAsyncSubscription)(subscription)).toHaveProperty('initial', initial); | ||
var subscription = createSyncSubscribable(initial); | ||
expect((0, _create.createRemoteSubscribable)(subscription)).toHaveProperty('initial', initial); | ||
}); | ||
@@ -56,6 +56,6 @@ it('retains subscriptions on subscribe', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
case 0: | ||
subscription = createSyncSubscription('abc'); | ||
subscription = createSyncSubscribable('abc'); | ||
subscriber = jest.fn(); | ||
_context.next = 4; | ||
return (0, _create.createAsyncSubscription)(subscription).subscribe(subscriber); | ||
return (0, _create.createRemoteSubscribable)(subscription).subscribe(subscriber); | ||
@@ -78,6 +78,6 @@ case 4: | ||
case 0: | ||
subscription = createSyncSubscription('abc'); | ||
subscription = createSyncSubscribable('abc'); | ||
subscriber = jest.fn(); | ||
_context2.next = 4; | ||
return (0, _create.createAsyncSubscription)(subscription).subscribe(subscriber); | ||
return (0, _create.createRemoteSubscribable)(subscription).subscribe(subscriber); | ||
@@ -97,3 +97,3 @@ case 4: | ||
it('returns a teardown function that releases the subscription and prevents future updates', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { | ||
var subscription, subscriber, _yield$createAsyncSub, _yield$createAsyncSub2, teardown; | ||
var subscription, subscriber, _yield$createRemoteSu, _yield$createRemoteSu2, teardown; | ||
@@ -104,11 +104,11 @@ return _regenerator["default"].wrap(function _callee3$(_context3) { | ||
case 0: | ||
subscription = createSyncSubscription('abc'); | ||
subscription = createSyncSubscribable('abc'); | ||
subscriber = jest.fn(); | ||
_context3.next = 4; | ||
return (0, _create.createAsyncSubscription)(subscription).subscribe(subscriber); | ||
return (0, _create.createRemoteSubscribable)(subscription).subscribe(subscriber); | ||
case 4: | ||
_yield$createAsyncSub = _context3.sent; | ||
_yield$createAsyncSub2 = _slicedToArray(_yield$createAsyncSub, 1); | ||
teardown = _yield$createAsyncSub2[0]; | ||
_yield$createRemoteSu = _context3.sent; | ||
_yield$createRemoteSu2 = _slicedToArray(_yield$createRemoteSu, 1); | ||
teardown = _yield$createRemoteSu2[0]; | ||
teardown(); | ||
@@ -127,3 +127,3 @@ expect(release).toHaveBeenCalledWith(subscriber); | ||
it('returns the current value when the subscription is made', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee4() { | ||
var subscription, newValue, _yield$createAsyncSub3, _yield$createAsyncSub4, value; | ||
var subscription, newValue, _yield$createRemoteSu3, _yield$createRemoteSu4, value; | ||
@@ -134,12 +134,12 @@ return _regenerator["default"].wrap(function _callee4$(_context4) { | ||
case 0: | ||
subscription = createSyncSubscription('abc'); | ||
subscription = createSyncSubscribable('abc'); | ||
newValue = 'xyz'; | ||
subscription.update(newValue); | ||
_context4.next = 5; | ||
return (0, _create.createAsyncSubscription)(subscription).subscribe(jest.fn()); | ||
return (0, _create.createRemoteSubscribable)(subscription).subscribe(jest.fn()); | ||
case 5: | ||
_yield$createAsyncSub3 = _context4.sent; | ||
_yield$createAsyncSub4 = _slicedToArray(_yield$createAsyncSub3, 2); | ||
value = _yield$createAsyncSub4[1]; | ||
_yield$createRemoteSu3 = _context4.sent; | ||
_yield$createRemoteSu4 = _slicedToArray(_yield$createRemoteSu3, 2); | ||
value = _yield$createRemoteSu4[1]; | ||
expect(value).toBe(newValue); | ||
@@ -156,9 +156,10 @@ | ||
function createSyncSubscription(initial) { | ||
function createSyncSubscribable(initial) { | ||
var current = initial; | ||
var subscribers = new Set(); | ||
return { | ||
getCurrentValue: function getCurrentValue() { | ||
get current() { | ||
return current; | ||
}, | ||
update: function update(value) { | ||
@@ -165,0 +166,0 @@ current = value; |
@@ -38,3 +38,3 @@ "use strict"; | ||
describe('createAsyncSubscription()', function () { | ||
describe('makeStatefulSubscribable()', function () { | ||
beforeEach(function () { | ||
@@ -45,4 +45,4 @@ release.mockReset(); | ||
it('retains the subscription', function () { | ||
var subscription = createAsyncSubscription(123); | ||
(0, _stateful.makeStateful)(subscription); | ||
var subscription = createRemoteSubscribable(123); | ||
(0, _stateful.makeStatefulSubscribable)(subscription); | ||
expect(retain).toHaveBeenCalledWith(subscription); | ||
@@ -56,4 +56,4 @@ }); | ||
case 0: | ||
subscription = createAsyncSubscription('abc'); | ||
statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
subscription = createRemoteSubscribable('abc'); | ||
statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
_context.next = 4; | ||
@@ -65,3 +65,3 @@ return subscription.resolve(); | ||
subscription.update(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
@@ -81,4 +81,4 @@ case 7: | ||
case 0: | ||
subscription = createAsyncSubscription('abc'); | ||
statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
subscription = createRemoteSubscribable('abc'); | ||
statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
_context2.next = 4; | ||
@@ -107,4 +107,4 @@ return subscription.resolve(); | ||
case 0: | ||
subscription = createAsyncSubscription('abc'); | ||
statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
subscription = createRemoteSubscribable('abc'); | ||
statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
subscriber = jest.fn(); | ||
@@ -119,3 +119,3 @@ statefulSubscription.subscribe(subscriber); | ||
expect(subscriber).toHaveBeenCalledWith(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
@@ -135,4 +135,4 @@ case 10: | ||
case 0: | ||
subscription = createAsyncSubscription('abc'); | ||
statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
subscription = createRemoteSubscribable('abc'); | ||
statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
_context4.next = 4; | ||
@@ -143,3 +143,3 @@ return subscription.resolve(); | ||
_context4.next = 6; | ||
return statefulSubscription.stop(); | ||
return statefulSubscription.destroy(); | ||
@@ -162,4 +162,4 @@ case 6: | ||
case 0: | ||
subscription = createAsyncSubscription('abc'); | ||
statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
subscription = createRemoteSubscribable('abc'); | ||
statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
subscriber = jest.fn(); | ||
@@ -169,3 +169,3 @@ statefulSubscription.subscribe(subscriber); | ||
subscription.update(newValue); | ||
statefulSubscription.stop(); | ||
statefulSubscription.destroy(); | ||
_context5.next = 9; | ||
@@ -177,3 +177,3 @@ return subscription.resolve(); | ||
expect(subscriber).not.toHaveBeenCalled(); | ||
expect(statefulSubscription.getCurrentValue()).not.toBe(newValue); | ||
expect(statefulSubscription.current).not.toBe(newValue); | ||
@@ -189,3 +189,3 @@ case 12: | ||
function createAsyncSubscription(initial) { | ||
function createRemoteSubscribable(initial) { | ||
var current = initial; | ||
@@ -192,0 +192,0 @@ var resolved = false; |
@@ -6,8 +6,8 @@ "use strict"; | ||
}); | ||
exports.createAsyncSubscription = createAsyncSubscription; | ||
exports.createRemoteSubscribable = createRemoteSubscribable; | ||
var _rpc = require("@remote-ui/rpc"); | ||
function createAsyncSubscription(subscription) { | ||
const initial = subscription.getCurrentValue(); | ||
function createRemoteSubscribable(subscription) { | ||
const initial = subscription.current; | ||
return { | ||
@@ -18,3 +18,3 @@ initial, | ||
(0, _rpc.retain)(subscriber); | ||
const unsubscribe = subscription.subscribe((value = subscription.getCurrentValue()) => { | ||
const unsubscribe = subscription.subscribe((value = subscription.current) => { | ||
subscriber(value); | ||
@@ -28,3 +28,3 @@ }); | ||
return [teardown, subscription.getCurrentValue()]; | ||
return [teardown, subscription.current]; | ||
} | ||
@@ -31,0 +31,0 @@ |
@@ -6,12 +6,12 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "makeStateful", { | ||
Object.defineProperty(exports, "makeStatefulSubscribable", { | ||
enumerable: true, | ||
get: function () { | ||
return _stateful.makeStateful; | ||
return _stateful.makeStatefulSubscribable; | ||
} | ||
}); | ||
Object.defineProperty(exports, "createAsyncSubscription", { | ||
Object.defineProperty(exports, "createRemoteSubscribable", { | ||
enumerable: true, | ||
get: function () { | ||
return _create.createAsyncSubscription; | ||
return _create.createRemoteSubscribable; | ||
} | ||
@@ -18,0 +18,0 @@ }); |
@@ -6,7 +6,7 @@ "use strict"; | ||
}); | ||
exports.makeStateful = makeStateful; | ||
exports.makeStatefulSubscribable = makeStatefulSubscribable; | ||
var _rpc = require("@remote-ui/rpc"); | ||
function makeStateful(subscription) { | ||
function makeStatefulSubscribable(subscription) { | ||
// We retain because it will automatically retain any functions we get from | ||
@@ -24,3 +24,3 @@ // calling functions on this object, which will automatically manage the memory | ||
return { | ||
getCurrentValue() { | ||
get current() { | ||
return current; | ||
@@ -36,9 +36,8 @@ }, | ||
stop() { | ||
async destroy() { | ||
listening = false; | ||
subscribers.clear(); | ||
return subscriptionResult.then(([unsubscribe]) => { | ||
unsubscribe(); | ||
(0, _rpc.release)(subscription); | ||
}); | ||
const [unsubscribe] = await subscriptionResult; | ||
unsubscribe(); | ||
(0, _rpc.release)(subscription); | ||
} | ||
@@ -45,0 +44,0 @@ |
@@ -13,3 +13,3 @@ "use strict"; | ||
} = jest.requireMock('@remote-ui/rpc'); | ||
describe('createAsyncSubscription()', () => { | ||
describe('createRemoteSubscribable()', () => { | ||
beforeEach(() => { | ||
@@ -21,15 +21,15 @@ release.mockReset(); | ||
const initial = 123; | ||
const subscription = createSyncSubscription(initial); | ||
expect((0, _create.createAsyncSubscription)(subscription)).toHaveProperty('initial', initial); | ||
const subscription = createSyncSubscribable(initial); | ||
expect((0, _create.createRemoteSubscribable)(subscription)).toHaveProperty('initial', initial); | ||
}); | ||
it('retains subscriptions on subscribe', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
await (0, _create.createAsyncSubscription)(subscription).subscribe(subscriber); | ||
await (0, _create.createRemoteSubscribable)(subscription).subscribe(subscriber); | ||
expect(retain).toHaveBeenCalledWith(subscriber); | ||
}); | ||
it('calls a subscription when the value changes', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
await (0, _create.createAsyncSubscription)(subscription).subscribe(subscriber); | ||
await (0, _create.createRemoteSubscribable)(subscription).subscribe(subscriber); | ||
const newValue = 'xyz'; | ||
@@ -40,5 +40,5 @@ subscription.update(newValue); | ||
it('returns a teardown function that releases the subscription and prevents future updates', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
const [teardown] = await (0, _create.createAsyncSubscription)(subscription).subscribe(subscriber); | ||
const [teardown] = await (0, _create.createRemoteSubscribable)(subscription).subscribe(subscriber); | ||
teardown(); | ||
@@ -50,6 +50,6 @@ expect(release).toHaveBeenCalledWith(subscriber); | ||
it('returns the current value when the subscription is made', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const newValue = 'xyz'; | ||
subscription.update(newValue); | ||
const [, value] = await (0, _create.createAsyncSubscription)(subscription).subscribe(jest.fn()); | ||
const [, value] = await (0, _create.createRemoteSubscribable)(subscription).subscribe(jest.fn()); | ||
expect(value).toBe(newValue); | ||
@@ -59,7 +59,9 @@ }); | ||
function createSyncSubscription(initial) { | ||
function createSyncSubscribable(initial) { | ||
let current = initial; | ||
const subscribers = new Set(); | ||
return { | ||
getCurrentValue: () => current, | ||
get current() { | ||
return current; | ||
}, | ||
@@ -66,0 +68,0 @@ update(value) { |
@@ -13,3 +13,3 @@ "use strict"; | ||
} = jest.requireMock('@remote-ui/rpc'); | ||
describe('createAsyncSubscription()', () => { | ||
describe('makeStatefulSubscribable()', () => { | ||
beforeEach(() => { | ||
@@ -20,17 +20,17 @@ release.mockReset(); | ||
it('retains the subscription', () => { | ||
const subscription = createAsyncSubscription(123); | ||
(0, _stateful.makeStateful)(subscription); | ||
const subscription = createRemoteSubscribable(123); | ||
(0, _stateful.makeStatefulSubscribable)(subscription); | ||
expect(retain).toHaveBeenCalledWith(subscription); | ||
}); | ||
it('keeps track of the current value', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
await subscription.resolve(); | ||
const newValue = 'xyz'; | ||
subscription.update(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
}); | ||
it('calls subscribers with new values', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
await subscription.resolve(); | ||
@@ -44,4 +44,4 @@ const subscriber = jest.fn(); | ||
it('updates the current value when the value has changed before subscription', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
const subscriber = jest.fn(); | ||
@@ -53,14 +53,14 @@ statefulSubscription.subscribe(subscriber); | ||
expect(subscriber).toHaveBeenCalledWith(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
}); | ||
it('releases the subscription when stopped', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
await subscription.resolve(); | ||
await statefulSubscription.stop(); | ||
await statefulSubscription.destroy(); | ||
expect(release).toHaveBeenCalledWith(subscription); | ||
}); | ||
it('unsubscribes from the subscription on stop, and does not apply any updates', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = (0, _stateful.makeStateful)(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = (0, _stateful.makeStatefulSubscribable)(subscription); | ||
const subscriber = jest.fn(); | ||
@@ -70,11 +70,11 @@ statefulSubscription.subscribe(subscriber); | ||
subscription.update(newValue); | ||
statefulSubscription.stop(); | ||
statefulSubscription.destroy(); | ||
await subscription.resolve(); | ||
expect(release).toHaveBeenCalledWith(subscription); | ||
expect(subscriber).not.toHaveBeenCalled(); | ||
expect(statefulSubscription.getCurrentValue()).not.toBe(newValue); | ||
expect(statefulSubscription.current).not.toBe(newValue); | ||
}); | ||
}); | ||
function createAsyncSubscription(initial) { | ||
function createRemoteSubscribable(initial) { | ||
let current = initial; | ||
@@ -81,0 +81,0 @@ let resolved = false; |
@@ -1,3 +0,3 @@ | ||
import type { SyncSubscription, AsyncSubscription } from './types'; | ||
export declare function createAsyncSubscription<T>(subscription: SyncSubscription<T>): AsyncSubscription<T>; | ||
import type { SyncSubscribable, RemoteSubscribable } from './types'; | ||
export declare function createRemoteSubscribable<T>(subscription: SyncSubscribable<T>): RemoteSubscribable<T>; | ||
//# sourceMappingURL=create.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createAsyncSubscription = void 0; | ||
exports.createRemoteSubscribable = void 0; | ||
const rpc_1 = require("@remote-ui/rpc"); | ||
function createAsyncSubscription(subscription) { | ||
const initial = subscription.getCurrentValue(); | ||
function createRemoteSubscribable(subscription) { | ||
const initial = subscription.current; | ||
return { | ||
@@ -11,3 +11,3 @@ initial, | ||
rpc_1.retain(subscriber); | ||
const unsubscribe = subscription.subscribe((value = subscription.getCurrentValue()) => { | ||
const unsubscribe = subscription.subscribe((value = subscription.current) => { | ||
subscriber(value); | ||
@@ -19,6 +19,6 @@ }); | ||
}; | ||
return [teardown, subscription.getCurrentValue()]; | ||
return [teardown, subscription.current]; | ||
}, | ||
}; | ||
} | ||
exports.createAsyncSubscription = createAsyncSubscription; | ||
exports.createRemoteSubscribable = createRemoteSubscribable; |
@@ -1,4 +0,4 @@ | ||
export { makeStateful } from './stateful'; | ||
export { createAsyncSubscription } from './create'; | ||
export type { AsyncSubscription, StatefulAsyncSubscription, SyncSubscription, } from './types'; | ||
export { makeStatefulSubscribable } from './stateful'; | ||
export { createRemoteSubscribable } from './create'; | ||
export type { SyncSubscribable, RemoteSubscribable, StatefulRemoteSubscribable, } from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var stateful_1 = require("./stateful"); | ||
Object.defineProperty(exports, "makeStateful", { enumerable: true, get: function () { return stateful_1.makeStateful; } }); | ||
Object.defineProperty(exports, "makeStatefulSubscribable", { enumerable: true, get: function () { return stateful_1.makeStatefulSubscribable; } }); | ||
var create_1 = require("./create"); | ||
Object.defineProperty(exports, "createAsyncSubscription", { enumerable: true, get: function () { return create_1.createAsyncSubscription; } }); | ||
Object.defineProperty(exports, "createRemoteSubscribable", { enumerable: true, get: function () { return create_1.createRemoteSubscribable; } }); |
@@ -1,3 +0,3 @@ | ||
import type { AsyncSubscription, StatefulAsyncSubscription } from './types'; | ||
export declare function makeStateful<T>(subscription: AsyncSubscription<T>): StatefulAsyncSubscription<T>; | ||
import type { RemoteSubscribable, StatefulRemoteSubscribable } from './types'; | ||
export declare function makeStatefulSubscribable<T>(subscription: RemoteSubscribable<T>): StatefulRemoteSubscribable<T>; | ||
//# sourceMappingURL=stateful.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.makeStateful = void 0; | ||
exports.makeStatefulSubscribable = void 0; | ||
const rpc_1 = require("@remote-ui/rpc"); | ||
function makeStateful(subscription) { | ||
function makeStatefulSubscribable(subscription) { | ||
// We retain because it will automatically retain any functions we get from | ||
@@ -18,3 +18,3 @@ // calling functions on this object, which will automatically manage the memory | ||
return { | ||
getCurrentValue() { | ||
get current() { | ||
return current; | ||
@@ -28,9 +28,8 @@ }, | ||
}, | ||
stop() { | ||
async destroy() { | ||
listening = false; | ||
subscribers.clear(); | ||
return subscriptionResult.then(([unsubscribe]) => { | ||
unsubscribe(); | ||
rpc_1.release(subscription); | ||
}); | ||
const [unsubscribe] = await subscriptionResult; | ||
unsubscribe(); | ||
rpc_1.release(subscription); | ||
}, | ||
@@ -47,2 +46,2 @@ }; | ||
} | ||
exports.makeStateful = makeStateful; | ||
exports.makeStatefulSubscribable = makeStatefulSubscribable; |
@@ -9,3 +9,3 @@ "use strict"; | ||
const { retain, release } = jest.requireMock('@remote-ui/rpc'); | ||
describe('createAsyncSubscription()', () => { | ||
describe('createRemoteSubscribable()', () => { | ||
beforeEach(() => { | ||
@@ -17,15 +17,15 @@ release.mockReset(); | ||
const initial = 123; | ||
const subscription = createSyncSubscription(initial); | ||
expect(create_1.createAsyncSubscription(subscription)).toHaveProperty('initial', initial); | ||
const subscription = createSyncSubscribable(initial); | ||
expect(create_1.createRemoteSubscribable(subscription)).toHaveProperty('initial', initial); | ||
}); | ||
it('retains subscriptions on subscribe', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
await create_1.createAsyncSubscription(subscription).subscribe(subscriber); | ||
await create_1.createRemoteSubscribable(subscription).subscribe(subscriber); | ||
expect(retain).toHaveBeenCalledWith(subscriber); | ||
}); | ||
it('calls a subscription when the value changes', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
await create_1.createAsyncSubscription(subscription).subscribe(subscriber); | ||
await create_1.createRemoteSubscribable(subscription).subscribe(subscriber); | ||
const newValue = 'xyz'; | ||
@@ -36,5 +36,5 @@ subscription.update(newValue); | ||
it('returns a teardown function that releases the subscription and prevents future updates', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
const [teardown] = await create_1.createAsyncSubscription(subscription).subscribe(subscriber); | ||
const [teardown] = await create_1.createRemoteSubscribable(subscription).subscribe(subscriber); | ||
teardown(); | ||
@@ -46,14 +46,16 @@ expect(release).toHaveBeenCalledWith(subscriber); | ||
it('returns the current value when the subscription is made', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const newValue = 'xyz'; | ||
subscription.update(newValue); | ||
const [, value] = await create_1.createAsyncSubscription(subscription).subscribe(jest.fn()); | ||
const [, value] = await create_1.createRemoteSubscribable(subscription).subscribe(jest.fn()); | ||
expect(value).toBe(newValue); | ||
}); | ||
}); | ||
function createSyncSubscription(initial) { | ||
function createSyncSubscribable(initial) { | ||
let current = initial; | ||
const subscribers = new Set(); | ||
return { | ||
getCurrentValue: () => current, | ||
get current() { | ||
return current; | ||
}, | ||
update(value) { | ||
@@ -60,0 +62,0 @@ current = value; |
@@ -9,3 +9,3 @@ "use strict"; | ||
const { retain, release } = jest.requireMock('@remote-ui/rpc'); | ||
describe('createAsyncSubscription()', () => { | ||
describe('makeStatefulSubscribable()', () => { | ||
beforeEach(() => { | ||
@@ -16,17 +16,17 @@ release.mockReset(); | ||
it('retains the subscription', () => { | ||
const subscription = createAsyncSubscription(123); | ||
stateful_1.makeStateful(subscription); | ||
const subscription = createRemoteSubscribable(123); | ||
stateful_1.makeStatefulSubscribable(subscription); | ||
expect(retain).toHaveBeenCalledWith(subscription); | ||
}); | ||
it('keeps track of the current value', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = stateful_1.makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = stateful_1.makeStatefulSubscribable(subscription); | ||
await subscription.resolve(); | ||
const newValue = 'xyz'; | ||
subscription.update(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
}); | ||
it('calls subscribers with new values', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = stateful_1.makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = stateful_1.makeStatefulSubscribable(subscription); | ||
await subscription.resolve(); | ||
@@ -40,4 +40,4 @@ const subscriber = jest.fn(); | ||
it('updates the current value when the value has changed before subscription', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = stateful_1.makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = stateful_1.makeStatefulSubscribable(subscription); | ||
const subscriber = jest.fn(); | ||
@@ -49,14 +49,14 @@ statefulSubscription.subscribe(subscriber); | ||
expect(subscriber).toHaveBeenCalledWith(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
}); | ||
it('releases the subscription when stopped', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = stateful_1.makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = stateful_1.makeStatefulSubscribable(subscription); | ||
await subscription.resolve(); | ||
await statefulSubscription.stop(); | ||
await statefulSubscription.destroy(); | ||
expect(release).toHaveBeenCalledWith(subscription); | ||
}); | ||
it('unsubscribes from the subscription on stop, and does not apply any updates', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = stateful_1.makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = stateful_1.makeStatefulSubscribable(subscription); | ||
const subscriber = jest.fn(); | ||
@@ -66,10 +66,10 @@ statefulSubscription.subscribe(subscriber); | ||
subscription.update(newValue); | ||
statefulSubscription.stop(); | ||
statefulSubscription.destroy(); | ||
await subscription.resolve(); | ||
expect(release).toHaveBeenCalledWith(subscription); | ||
expect(subscriber).not.toHaveBeenCalled(); | ||
expect(statefulSubscription.getCurrentValue()).not.toBe(newValue); | ||
expect(statefulSubscription.current).not.toBe(newValue); | ||
}); | ||
}); | ||
function createAsyncSubscription(initial) { | ||
function createRemoteSubscribable(initial) { | ||
let current = initial; | ||
@@ -76,0 +76,0 @@ let resolved = false; |
import type { MaybePromise } from '@remote-ui/rpc'; | ||
export declare type Subscriber<T> = (value: T) => void; | ||
export declare type AsyncSubscribeResult<T> = [() => void, T]; | ||
export interface AsyncSubscription<T> { | ||
export declare type RemoteSubscribeResult<T> = [() => void, T]; | ||
export interface SyncSubscribable<T> { | ||
readonly current: T; | ||
subscribe(subscriber: Subscriber<T>): () => void; | ||
} | ||
export interface RemoteSubscribable<T> { | ||
readonly initial: T; | ||
subscribe(subscriber: Subscriber<T>): MaybePromise<AsyncSubscribeResult<T>>; | ||
subscribe(subscriber: Subscriber<T>): MaybePromise<RemoteSubscribeResult<T>>; | ||
} | ||
export interface SyncSubscription<T> { | ||
getCurrentValue(): T; | ||
subscribe(subscriber: Subscriber<T>): () => void; | ||
export interface StatefulRemoteSubscribable<T> extends SyncSubscribable<T> { | ||
destroy(): Promise<void>; | ||
} | ||
export interface StatefulAsyncSubscription<T> extends SyncSubscription<T> { | ||
stop(): Promise<void>; | ||
} | ||
//# sourceMappingURL=types.d.ts.map |
@@ -10,2 +10,8 @@ # Changelog | ||
## [2.0.0] - 2021-02-08 | ||
### Changed | ||
- **Breaking:** changed all type and function names to be more accurate and to decouple the library from React. | ||
## [1.0.2] - 2020-06-24 | ||
@@ -12,0 +18,0 @@ |
{ | ||
"name": "@remote-ui/async-subscription", | ||
"version": "1.1.0-alpha.0", | ||
"version": "2.0.0", | ||
"publishConfig": { | ||
@@ -15,5 +15,5 @@ "access": "public", | ||
".": { | ||
"esnext": "./index.esnext", | ||
"import": "./index.mjs", | ||
"require": "./index.js", | ||
"esnext": "./index.esnext" | ||
"require": "./index.js" | ||
}, | ||
@@ -24,5 +24,5 @@ "./": "./" | ||
"dependencies": { | ||
"@remote-ui/rpc": "^1.1.0-alpha.0" | ||
"@remote-ui/rpc": "^1.0.17" | ||
}, | ||
"gitHead": "95b058fdbc84958f3e10bb4dfd8029a6f0189078" | ||
"gitHead": "062fade9805fe58f5b22cf1c7921615526528689" | ||
} |
@@ -23,11 +23,11 @@ # `@remote-ui/async-subscription` | ||
1. A synchronous subscription (`SyncSubscription`), which allows synchronous access to the current value with `getCurrentValue()`, and allows registering and unregistering a callback synchronously with `subscribe()`. The signature for this function is modelled after the [React `useSubscription()` definition](https://github.com/facebook/react/tree/master/packages/use-subscription) of a subscription. | ||
1. An asynchronous subscription (`AsyncSubscription`), which provides an `initial` value synchronously, and an asynchronous `subscribe()` function that that can register for all changes to their subscribed value, as documented below. | ||
1. A stateful asynchronous subscription (`StatefulAsyncSubscription`), which is based on `AsyncSubscription`, but presents the API of a `SyncSubscription`. | ||
1. A synchronous subscription (`SyncSubscribable`), which allows synchronous access to the current value with the `current` property, and allows registering and registering a callback synchronously with `subscribe()`. | ||
1. A remote subscription (`RemoteSubscribable`), which provides an `initial` value synchronously, and an asynchronous `subscribe()` function that that can register for all changes to their subscribed value, as documented below. | ||
1. A stateful remote subscription (`StatefulRemoteSubscribable`), which is based on `RemoteSubscribable`, but presents the API of a `SyncSubscribable`. | ||
When providing a subscription to a remote-ui container, you will generally need the host to convert its `SyncSubscription` into an `AsyncSubscription`, which you can then safely pass to the remote context. Once there, you can use it directly, or wrap it as a `StatefulAsyncSubscription` to continuously provide the most recent value synchronously (rather than merely relying on the initial value, and asynchronously updating it for each subscriber). | ||
When providing a subscription to a remote-ui container, you will generally need the host to convert its `SyncSubscribable` into an `RemoteSubscribable`, which you can then safely pass to the remote context. Once there, you can use it directly, or wrap it as a `StatefulRemoteSubscribable` to continuously provide the most recent value synchronously (rather than merely relying on the initial value, and asynchronously updating it for each subscriber). | ||
This library provides utilities to do both parts of this job. | ||
### `createAsyncSubscription()` | ||
### `createRemoteSubscribable()` | ||
@@ -37,3 +37,3 @@ This function accepts a synchronous subscription, and returns its asynchronous version. | ||
```ts | ||
import {createAsyncSubscription} from '@remote-ui/async-subscription'; | ||
import {createRemoteSubscribable} from '@remote-ui/async-subscription'; | ||
@@ -44,4 +44,6 @@ const input = document.createElement('input'); | ||
// the input’s initial value, and add an event listener for updates. | ||
const subscription = createAsyncSubscription<string>({ | ||
getCurrentValue: () => input.value, | ||
const subscription = createRemoteSubscribable<string>({ | ||
get current() { | ||
return input.value; | ||
}, | ||
subscribe(subscriber) { | ||
@@ -63,15 +65,18 @@ function listener(event: Event) { | ||
## `makeStateful()` | ||
## `makeStatefulSubscribable()` | ||
This function accepts an asynchronous subscription, and returns a “stateful” asynchronous subscription. This type of subscription will immediately subscribe (and update the current value, if it ends up being different after the initial subscription promise resolves), and will continuously reflect the most recent value it finds in its `getCurrentValue()` method. It also retains the subscription. | ||
This function accepts a remote subscription, and returns a “stateful” remote subscription. This type of subscription will immediately subscribe (and update the current value, if it ends up being different after the initial subscription promise resolves), and will continuously reflect the most recent value it finds in its `getCurrentValue()` method. It also retains the subscription. | ||
The `subscribe()` method behaves as if it were asynchronous (returning a function that can be used to unsubscribe), but this does not remove the “core” listener on the subscription that maintains the stateful value. To permanently destroy the statefulness of the subscription, you can call the `stop()` method on the resulting subscription. | ||
The `subscribe()` method behaves as if it were synchronous (returning a function that can be used to unsubscribe), but this does not remove the “core” listener on the subscription that maintains the stateful value. To permanently destroy the statefulness of the subscription, you can call the `destroy()` method on the resulting subscription. | ||
```ts | ||
import {makeStateful, AsyncSubscription} from '@remote-ui/async-subscription'; | ||
import { | ||
makeStatefulSubscribable, | ||
RemoteSubscribable, | ||
} from '@remote-ui/async-subscription'; | ||
// In the remote context... | ||
function receiveSubscription(subscription: AsyncSubscription) { | ||
const statefulSubscription = makeStateful(subscription); | ||
function receiveSubscription<T>(subscription: RemoteSubscribable<T>) { | ||
const statefulSubscription = makeStatefulSubscribable(subscription); | ||
@@ -78,0 +83,0 @@ const unsubscribe = statefulSubscription.subscribe((value) => { |
import {retain, release} from '@remote-ui/rpc'; | ||
import type {SyncSubscription, AsyncSubscription} from './types'; | ||
import type {SyncSubscribable, RemoteSubscribable} from './types'; | ||
export function createAsyncSubscription<T>( | ||
subscription: SyncSubscription<T>, | ||
): AsyncSubscription<T> { | ||
const initial = subscription.getCurrentValue(); | ||
export function createRemoteSubscribable<T>( | ||
subscription: SyncSubscribable<T>, | ||
): RemoteSubscribable<T> { | ||
const initial = subscription.current; | ||
@@ -15,3 +15,3 @@ return { | ||
const unsubscribe = subscription.subscribe( | ||
(value = subscription.getCurrentValue()) => { | ||
(value = subscription.current) => { | ||
subscriber(value); | ||
@@ -26,5 +26,5 @@ }, | ||
return [teardown, subscription.getCurrentValue()]; | ||
return [teardown, subscription.current]; | ||
}, | ||
}; | ||
} |
@@ -1,7 +0,7 @@ | ||
export {makeStateful} from './stateful'; | ||
export {createAsyncSubscription} from './create'; | ||
export {makeStatefulSubscribable} from './stateful'; | ||
export {createRemoteSubscribable} from './create'; | ||
export type { | ||
AsyncSubscription, | ||
StatefulAsyncSubscription, | ||
SyncSubscription, | ||
SyncSubscribable, | ||
RemoteSubscribable, | ||
StatefulRemoteSubscribable, | ||
} from './types'; |
import {retain, release} from '@remote-ui/rpc'; | ||
import type { | ||
Subscriber, | ||
AsyncSubscription, | ||
AsyncSubscribeResult, | ||
StatefulAsyncSubscription, | ||
RemoteSubscribable, | ||
RemoteSubscribeResult, | ||
StatefulRemoteSubscribable, | ||
} from './types'; | ||
export function makeStateful<T>( | ||
subscription: AsyncSubscription<T>, | ||
): StatefulAsyncSubscription<T> { | ||
export function makeStatefulSubscribable<T>( | ||
subscription: RemoteSubscribable<T>, | ||
): StatefulRemoteSubscribable<T> { | ||
// We retain because it will automatically retain any functions we get from | ||
@@ -22,3 +22,3 @@ // calling functions on this object, which will automatically manage the memory | ||
const subscriptionResult = Promise.resolve<AsyncSubscribeResult<T>>( | ||
const subscriptionResult = Promise.resolve<RemoteSubscribeResult<T>>( | ||
subscription.subscribe(listener), | ||
@@ -31,3 +31,3 @@ ).then((result) => { | ||
return { | ||
getCurrentValue() { | ||
get current() { | ||
return current; | ||
@@ -42,10 +42,9 @@ }, | ||
}, | ||
stop() { | ||
async destroy() { | ||
listening = false; | ||
subscribers.clear(); | ||
return subscriptionResult.then(([unsubscribe]) => { | ||
unsubscribe(); | ||
release(subscription); | ||
}); | ||
const [unsubscribe] = await subscriptionResult; | ||
unsubscribe(); | ||
release(subscription); | ||
}, | ||
@@ -52,0 +51,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
import {createAsyncSubscription} from '../create'; | ||
import type {SyncSubscription} from '../types'; | ||
import {createRemoteSubscribable} from '../create'; | ||
import type {SyncSubscribable} from '../types'; | ||
@@ -14,3 +14,3 @@ jest.mock('@remote-ui/rpc', () => ({ | ||
describe('createAsyncSubscription()', () => { | ||
describe('createRemoteSubscribable()', () => { | ||
beforeEach(() => { | ||
@@ -23,4 +23,4 @@ release.mockReset(); | ||
const initial = 123; | ||
const subscription = createSyncSubscription(initial); | ||
expect(createAsyncSubscription(subscription)).toHaveProperty( | ||
const subscription = createSyncSubscribable(initial); | ||
expect(createRemoteSubscribable(subscription)).toHaveProperty( | ||
'initial', | ||
@@ -32,5 +32,5 @@ initial, | ||
it('retains subscriptions on subscribe', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
await createAsyncSubscription(subscription).subscribe(subscriber); | ||
await createRemoteSubscribable(subscription).subscribe(subscriber); | ||
expect(retain).toHaveBeenCalledWith(subscriber); | ||
@@ -40,6 +40,6 @@ }); | ||
it('calls a subscription when the value changes', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
await createAsyncSubscription(subscription).subscribe(subscriber); | ||
await createRemoteSubscribable(subscription).subscribe(subscriber); | ||
@@ -53,5 +53,5 @@ const newValue = 'xyz'; | ||
it('returns a teardown function that releases the subscription and prevents future updates', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const subscriber = jest.fn(); | ||
const [teardown] = await createAsyncSubscription(subscription).subscribe( | ||
const [teardown] = await createRemoteSubscribable(subscription).subscribe( | ||
subscriber, | ||
@@ -70,7 +70,7 @@ ); | ||
it('returns the current value when the subscription is made', async () => { | ||
const subscription = createSyncSubscription('abc'); | ||
const subscription = createSyncSubscribable('abc'); | ||
const newValue = 'xyz'; | ||
subscription.update(newValue); | ||
const [, value] = await createAsyncSubscription(subscription).subscribe( | ||
const [, value] = await createRemoteSubscribable(subscription).subscribe( | ||
jest.fn(), | ||
@@ -83,12 +83,14 @@ ); | ||
function createSyncSubscription<T>( | ||
function createSyncSubscribable<T>( | ||
initial: T, | ||
): SyncSubscription<T> & {update(value: T): void} { | ||
): SyncSubscribable<T> & {update(value: T): void} { | ||
let current = initial; | ||
const subscribers = new Set< | ||
Parameters<SyncSubscription<T>['subscribe']>[0] | ||
Parameters<SyncSubscribable<T>['subscribe']>[0] | ||
>(); | ||
return { | ||
getCurrentValue: () => current, | ||
get current() { | ||
return current; | ||
}, | ||
update(value) { | ||
@@ -95,0 +97,0 @@ current = value; |
@@ -1,3 +0,3 @@ | ||
import {makeStateful} from '../stateful'; | ||
import type {AsyncSubscription} from '../types'; | ||
import {makeStatefulSubscribable} from '../stateful'; | ||
import type {RemoteSubscribable} from '../types'; | ||
@@ -14,3 +14,3 @@ jest.mock('@remote-ui/rpc', () => ({ | ||
describe('createAsyncSubscription()', () => { | ||
describe('makeStatefulSubscribable()', () => { | ||
beforeEach(() => { | ||
@@ -22,4 +22,4 @@ release.mockReset(); | ||
it('retains the subscription', () => { | ||
const subscription = createAsyncSubscription(123); | ||
makeStateful(subscription); | ||
const subscription = createRemoteSubscribable(123); | ||
makeStatefulSubscribable(subscription); | ||
expect(retain).toHaveBeenCalledWith(subscription); | ||
@@ -29,4 +29,4 @@ }); | ||
it('keeps track of the current value', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = makeStatefulSubscribable(subscription); | ||
await subscription.resolve(); | ||
@@ -37,8 +37,8 @@ | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
}); | ||
it('calls subscribers with new values', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = makeStatefulSubscribable(subscription); | ||
await subscription.resolve(); | ||
@@ -56,4 +56,4 @@ | ||
it('updates the current value when the value has changed before subscription', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = makeStatefulSubscribable(subscription); | ||
const subscriber = jest.fn(); | ||
@@ -68,11 +68,11 @@ statefulSubscription.subscribe(subscriber); | ||
expect(subscriber).toHaveBeenCalledWith(newValue); | ||
expect(statefulSubscription.getCurrentValue()).toBe(newValue); | ||
expect(statefulSubscription.current).toBe(newValue); | ||
}); | ||
it('releases the subscription when stopped', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = makeStatefulSubscribable(subscription); | ||
await subscription.resolve(); | ||
await statefulSubscription.stop(); | ||
await statefulSubscription.destroy(); | ||
@@ -83,4 +83,4 @@ expect(release).toHaveBeenCalledWith(subscription); | ||
it('unsubscribes from the subscription on stop, and does not apply any updates', async () => { | ||
const subscription = createAsyncSubscription('abc'); | ||
const statefulSubscription = makeStateful(subscription); | ||
const subscription = createRemoteSubscribable('abc'); | ||
const statefulSubscription = makeStatefulSubscribable(subscription); | ||
const subscriber = jest.fn(); | ||
@@ -92,3 +92,3 @@ statefulSubscription.subscribe(subscriber); | ||
statefulSubscription.stop(); | ||
statefulSubscription.destroy(); | ||
await subscription.resolve(); | ||
@@ -98,13 +98,13 @@ | ||
expect(subscriber).not.toHaveBeenCalled(); | ||
expect(statefulSubscription.getCurrentValue()).not.toBe(newValue); | ||
expect(statefulSubscription.current).not.toBe(newValue); | ||
}); | ||
}); | ||
function createAsyncSubscription<T>( | ||
function createRemoteSubscribable<T>( | ||
initial: T, | ||
): AsyncSubscription<T> & {update(value: T): void; resolve(): Promise<void>} { | ||
): RemoteSubscribable<T> & {update(value: T): void; resolve(): Promise<void>} { | ||
let current = initial; | ||
let resolved = false; | ||
const subscribers = new Set< | ||
Parameters<AsyncSubscription<T>['subscribe']>[0] | ||
Parameters<RemoteSubscribable<T>['subscribe']>[0] | ||
>(); | ||
@@ -111,0 +111,0 @@ const promises = new Set<Promise<void>>(); |
@@ -5,17 +5,16 @@ import type {MaybePromise} from '@remote-ui/rpc'; | ||
export type AsyncSubscribeResult<T> = [() => void, T]; | ||
export type RemoteSubscribeResult<T> = [() => void, T]; | ||
export interface AsyncSubscription<T> { | ||
readonly initial: T; | ||
subscribe(subscriber: Subscriber<T>): MaybePromise<AsyncSubscribeResult<T>>; | ||
export interface SyncSubscribable<T> { | ||
readonly current: T; | ||
subscribe(subscriber: Subscriber<T>): () => void; | ||
} | ||
// @see https://github.com/facebook/react/tree/master/packages/use-subscription | ||
export interface SyncSubscription<T> { | ||
getCurrentValue(): T; | ||
subscribe(subscriber: Subscriber<T>): () => void; | ||
export interface RemoteSubscribable<T> { | ||
readonly initial: T; | ||
subscribe(subscriber: Subscriber<T>): MaybePromise<RemoteSubscribeResult<T>>; | ||
} | ||
export interface StatefulAsyncSubscription<T> extends SyncSubscription<T> { | ||
stop(): Promise<void>; | ||
export interface StatefulRemoteSubscribable<T> extends SyncSubscribable<T> { | ||
destroy(): Promise<void>; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
372436
1745
1
91
0
Updated@remote-ui/rpc@^1.0.17