@scrypted/server 0.7.22 → 0.7.24

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.

Potentially problematic release.


This version of @scrypted/server might be problematic. Click here for more details.

Files changed (84) hide show
  1. package/dist/asynciterable-utils.d.ts +2 -0
  2. package/dist/cert.d.ts +6 -0
  3. package/dist/collection.d.ts +1 -0
  4. package/dist/db-types.d.ts +38 -0
  5. package/dist/event-registry.d.ts +19 -0
  6. package/dist/http-interfaces.d.ts +3 -0
  7. package/dist/infer-defaults.d.ts +11 -0
  8. package/dist/io.d.ts +22 -0
  9. package/dist/level.d.ts +110 -0
  10. package/dist/listen-zero.d.ts +10 -0
  11. package/dist/logger.d.ts +29 -0
  12. package/dist/media-helpers.d.ts +5 -0
  13. package/dist/mixin/mixin-cycle.d.ts +3 -0
  14. package/dist/plugin/acl.d.ts +16 -0
  15. package/dist/plugin/descriptor.d.ts +22 -0
  16. package/dist/plugin/media.d.ts +71 -0
  17. package/dist/plugin/plugin-api.d.ts +106 -0
  18. package/dist/plugin/plugin-console.d.ts +28 -0
  19. package/dist/plugin/plugin-debug.d.ts +4 -0
  20. package/dist/plugin/plugin-device.d.ts +54 -0
  21. package/dist/plugin/plugin-error.d.ts +2 -0
  22. package/dist/plugin/plugin-host-api.d.ts +43 -0
  23. package/dist/plugin/plugin-host.d.ts +45 -0
  24. package/dist/plugin/plugin-host.js +8 -25
  25. package/dist/plugin/plugin-host.js.map +1 -1
  26. package/dist/plugin/plugin-http.d.ts +18 -0
  27. package/dist/plugin/plugin-lazy-remote.d.ts +31 -0
  28. package/dist/plugin/plugin-npm-dependencies.d.ts +2 -0
  29. package/dist/plugin/plugin-remote-stats.d.ts +8 -0
  30. package/dist/plugin/plugin-remote-websocket.d.ts +29 -0
  31. package/dist/plugin/plugin-remote-worker.d.ts +2 -0
  32. package/dist/plugin/plugin-remote-worker.js +4 -4
  33. package/dist/plugin/plugin-remote-worker.js.map +1 -1
  34. package/dist/plugin/plugin-remote.d.ts +75 -0
  35. package/dist/plugin/plugin-repl.d.ts +2 -0
  36. package/dist/plugin/plugin-state-check.d.ts +1 -0
  37. package/dist/plugin/plugin-volume.d.ts +3 -0
  38. package/dist/plugin/runtime/child-process-worker.d.ts +20 -0
  39. package/dist/plugin/runtime/node-fork-worker.d.ts +9 -0
  40. package/dist/plugin/runtime/node-fork-worker.js.map +1 -1
  41. package/dist/plugin/runtime/node-thread-worker.d.ts +20 -0
  42. package/dist/plugin/runtime/python-worker.d.ts +10 -0
  43. package/dist/plugin/runtime/runtime-worker.d.ts +26 -0
  44. package/dist/plugin/socket-serializer.d.ts +5 -0
  45. package/dist/plugin/system.d.ts +39 -0
  46. package/dist/rpc-buffer-serializer.d.ts +11 -0
  47. package/dist/rpc-serializer.d.ts +24 -0
  48. package/dist/rpc.d.ts +132 -0
  49. package/dist/runtime.d.ts +103 -0
  50. package/dist/runtime.js +5 -0
  51. package/dist/runtime.js.map +1 -1
  52. package/dist/scrypted-main-exports.d.ts +6 -0
  53. package/dist/scrypted-main-exports.js +7 -2
  54. package/dist/scrypted-main-exports.js.map +1 -1
  55. package/dist/scrypted-main.d.ts +1 -0
  56. package/dist/scrypted-plugin-main.d.ts +2 -0
  57. package/dist/scrypted-server-main.d.ts +6 -0
  58. package/dist/scrypted-server-main.js +2 -1
  59. package/dist/scrypted-server-main.js.map +1 -1
  60. package/dist/server-settings.d.ts +5 -0
  61. package/dist/services/addresses.d.ts +7 -0
  62. package/dist/services/alerts.d.ts +9 -0
  63. package/dist/services/cors.d.ts +18 -0
  64. package/dist/services/info.d.ts +5 -0
  65. package/dist/services/plugin.d.ts +46 -0
  66. package/dist/services/service-control.d.ts +8 -0
  67. package/dist/services/users.d.ts +14 -0
  68. package/dist/sleep.d.ts +1 -0
  69. package/dist/state.d.ts +39 -0
  70. package/dist/threading.d.ts +3 -0
  71. package/dist/usertoken.d.ts +11 -0
  72. package/package.json +2 -1
  73. package/python/rpc-iterator-test.py +7 -3
  74. package/python/rpc.py +8 -0
  75. package/src/plugin/plugin-host.ts +10 -25
  76. package/src/plugin/plugin-remote-worker.ts +4 -4
  77. package/src/plugin/runtime/node-fork-worker.ts +3 -3
  78. package/src/plugin/runtime/runtime-worker.ts +1 -1
  79. package/src/runtime.ts +9 -0
  80. package/src/scrypted-main-exports.ts +9 -2
  81. package/src/scrypted-plugin-main.ts +1 -1
  82. package/src/scrypted-server-main.ts +6 -1
  83. package/test/rpc-python-test.ts +10 -6
  84. package/tsconfig.json +1 -0
@@ -0,0 +1,46 @@
1
+ /// <reference types="node" />
2
+ import { ScryptedNativeId } from "@scrypted/types";
3
+ import { ScryptedRuntime } from "../runtime";
4
+ export declare class PluginComponent {
5
+ scrypted: ScryptedRuntime;
6
+ constructor(scrypted: ScryptedRuntime);
7
+ renameDeviceId(id: string, newId: string): Promise<void>;
8
+ getStorage(id: string): {
9
+ [key: string]: string;
10
+ };
11
+ setStorage(id: string, storage: {
12
+ [key: string]: string;
13
+ }): Promise<void>;
14
+ setMixins(id: string, mixins: string[]): Promise<void>;
15
+ getIdForPluginId(pluginId: string): Promise<string>;
16
+ getIdForNativeId(pluginId: string, nativeId: ScryptedNativeId): Promise<string>;
17
+ reload(pluginId: string): Promise<void>;
18
+ kill(pluginId: string): Promise<void>;
19
+ getPackageJson(pluginId: string): Promise<any>;
20
+ getDeviceInfo(id: string): Promise<{
21
+ mixins: any;
22
+ pluginId: string;
23
+ storage: {
24
+ [key: string]: string;
25
+ };
26
+ nativeId: string;
27
+ }>;
28
+ getPluginInfo(pluginId: string): Promise<{
29
+ pid: number;
30
+ stats: {
31
+ cpuUsage: NodeJS.CpuUsage;
32
+ memoryUsage: NodeJS.MemoryUsage;
33
+ };
34
+ rpcObjects: number;
35
+ packageJson: any;
36
+ pendingResults: number;
37
+ id: string;
38
+ }>;
39
+ installNpm(pkg: string, version?: string): Promise<void>;
40
+ npmInfo(endpoint: string): Promise<any>;
41
+ updatePlugins(): Promise<void>;
42
+ clearConsole(id: string): Promise<void>;
43
+ getRemoteServicePort(pluginId: string, name: string, ...args: any[]): Promise<number>;
44
+ setHostParam(pluginId: string, name: string, param?: any): Promise<void>;
45
+ getHostParam(pluginId: string, name: string): Promise<any>;
46
+ }
@@ -0,0 +1,8 @@
1
+ import { ScryptedRuntime } from "../runtime";
2
+ export declare class ServiceControl {
3
+ scrypted: ScryptedRuntime;
4
+ constructor(scrypted: ScryptedRuntime);
5
+ exit(): Promise<void>;
6
+ restart(): Promise<void>;
7
+ update(): Promise<any>;
8
+ }
@@ -0,0 +1,14 @@
1
+ import { ScryptedUser } from "../db-types";
2
+ import { ScryptedRuntime } from "../runtime";
3
+ export declare class UsersService {
4
+ scrypted: ScryptedRuntime;
5
+ constructor(scrypted: ScryptedRuntime);
6
+ getAllUsers(): Promise<{
7
+ username: string;
8
+ admin: boolean;
9
+ }[]>;
10
+ removeUser(username: string): Promise<void>;
11
+ removeAllUsers(): Promise<void>;
12
+ addUser(username: string, password: string, aclId: string): Promise<void>;
13
+ }
14
+ export declare function setScryptedUserPassword(user: ScryptedUser, password: string, timestamp: number): void;
@@ -0,0 +1 @@
1
+ export declare function sleep(ms: number): Promise<void>;
@@ -0,0 +1,39 @@
1
+ /// <reference types="lodash" />
2
+ import { EventDetails, EventListenerOptions, EventListenerRegister, ScryptedInterface, SystemDeviceState } from "@scrypted/types";
3
+ import { PluginDevice } from "./db-types";
4
+ import { EventRegistry } from "./event-registry";
5
+ import { ScryptedRuntime } from "./runtime";
6
+ export declare class ScryptedStateManager extends EventRegistry {
7
+ scrypted: ScryptedRuntime;
8
+ upserts: Set<string>;
9
+ upsertThrottle: import("lodash").DebouncedFunc<() => void>;
10
+ constructor(scrypted: ScryptedRuntime);
11
+ getImplementerId(pluginDevice: PluginDevice, eventInterface: ScryptedInterface | string): Promise<string>;
12
+ notifyInterfaceEventFromMixin(pluginDevice: PluginDevice, eventInterface: ScryptedInterface | string, value: any, mixinId: string): Promise<void>;
13
+ setPluginDeviceStateFromMixin(pluginDevice: PluginDevice, property: string, value: any, eventInterface: ScryptedInterface, mixinId: string): Promise<boolean>;
14
+ setPluginDeviceState(device: PluginDevice, property: string, value: any, eventInterface?: ScryptedInterface): boolean;
15
+ updateDescriptor(device: PluginDevice): void;
16
+ removeDevice(id: string): void;
17
+ notifyInterfaceEvent(device: PluginDevice, eventInterface: ScryptedInterface | string, value: any, mixinId?: string): void;
18
+ setState(id: string, property: string, value: any): boolean;
19
+ getSystemState(): {
20
+ [id: string]: {
21
+ [property: string]: SystemDeviceState;
22
+ };
23
+ };
24
+ listenDevice(id: string, options: string | EventListenerOptions, callback: (eventDetails: EventDetails, eventData: any) => void): EventListenerRegister;
25
+ refreshThrottles: {
26
+ [id: string]: RefreshThrottle;
27
+ };
28
+ getOrCreateRefreshThrottle(id: string, refreshInterface: string, userInitiated: boolean): RefreshThrottle;
29
+ refresh(id: string, refreshInterface: string, userInitiated: boolean): Promise<void>;
30
+ }
31
+ interface RefreshThrottle {
32
+ promise: Promise<void>;
33
+ refreshInterface: string;
34
+ userInitiated: boolean;
35
+ tailRefresh: boolean;
36
+ }
37
+ export declare function setState(pluginDevice: PluginDevice, property: string, value: any): boolean;
38
+ export declare function getState(pluginDevice: PluginDevice, property: string): any;
39
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare function newThread<T>(thread: () => Promise<T>): Promise<T>;
2
+ export declare function newThread<V, T>(params: V, thread: (params: V) => Promise<T>): Promise<T>;
3
+ export declare function newThread<M, V, T>(modules: M, params: V, thread: (params: M & V) => Promise<T>): Promise<T>;
@@ -0,0 +1,11 @@
1
+ export declare const ONE_DAY_MILLISECONDS = 86400000;
2
+ export declare const ONE_YEAR_MILLISECONDS: number;
3
+ export declare class UserToken {
4
+ username: string;
5
+ aclId: string;
6
+ timestamp: number;
7
+ duration: number;
8
+ constructor(username: string, aclId: string, timestamp?: number, duration?: number);
9
+ static validateToken(token: string): UserToken;
10
+ toString(): string;
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrypted/server",
3
- "version": "0.7.22",
3
+ "version": "0.7.24",
4
4
  "description": "",
5
5
  "dependencies": {
6
6
  "@mapbox/node-pre-gyp": "^1.0.10",
@@ -61,6 +61,7 @@
61
61
  "scrypted-serve": "bin/scrypted-serve"
62
62
  },
63
63
  "main": "dist/scrypted-main-exports.js",
64
+ "types": "dist/scrypted-main-exports.d.ts",
64
65
  "scripts": {
65
66
  "preserve": "npm run build",
66
67
  "serve": "node --expose-gc dist/scrypted-main.js",
@@ -1,13 +1,13 @@
1
1
  import asyncio
2
2
  import rpc
3
- from rpc_reader import prepare_peer_readloop
3
+ from rpc_reader import prepare_peer_readloop, RpcFileTransport
4
4
  import traceback
5
5
 
6
6
  class Bar:
7
7
  pass
8
8
 
9
9
  async def main():
10
- peer, peerReadLoop = await prepare_peer_readloop(loop, 4, 3)
10
+ peer, peerReadLoop = await prepare_peer_readloop(loop, RpcFileTransport(4, 3))
11
11
  peer.params['foo'] = 3
12
12
  jsoncopy = {}
13
13
  jsoncopy[rpc.RpcPeer.PROPERTY_JSON_COPY_SERIALIZE_CHILDREN] = True
@@ -35,8 +35,12 @@ async def main():
35
35
  test = await peer.getParam('test')
36
36
  print(test)
37
37
  try:
38
- async for c in test:
38
+ i = 0
39
+ async for c in await test():
39
40
  print(c)
41
+ if i == 5:
42
+ break
43
+ i = i + 1
40
44
  except:
41
45
  traceback.print_exc()
42
46
  print('all done iterating')
package/python/rpc.py CHANGED
@@ -79,6 +79,14 @@ class RpcProxy(object):
79
79
  raise
80
80
  raise Exception('RpcProxy is not an async iterable')
81
81
 
82
+ async def aclose(self):
83
+ if self.__dict__[RpcPeer.PROPERTY_PROXY_PROPERTIES] and 'Symbol(Symbol.asyncIterator)' in self.__dict__[RpcPeer.PROPERTY_PROXY_PROPERTIES]:
84
+ try:
85
+ return await RpcProxyMethod(self, self.__dict__[RpcPeer.PROPERTY_PROXY_PROPERTIES]['Symbol(Symbol.asyncIterator)']['return'])()
86
+ except RPCResultError as e:
87
+ pass
88
+ raise Exception('RpcProxy is not an async iterable')
89
+
82
90
  def __getattr__(self, name):
83
91
  if name == '__proxy_finalizer_id':
84
92
  return self.dict['__proxy_entry']['finalizerId']
@@ -26,9 +26,6 @@ import { LazyRemote } from './plugin-lazy-remote';
26
26
  import { setupPluginRemote } from './plugin-remote';
27
27
  import { WebSocketConnection } from './plugin-remote-websocket';
28
28
  import { ensurePluginVolume, getScryptedVolume } from './plugin-volume';
29
- import { NodeForkWorker } from './runtime/node-fork-worker';
30
- import { NodeThreadWorker } from './runtime/node-thread-worker';
31
- import { PythonRuntimeWorker } from './runtime/python-worker';
32
29
  import { RuntimeWorker } from './runtime/runtime-worker';
33
30
 
34
31
  const serverVersion = require('../../package.json').version;
@@ -288,29 +285,17 @@ export class PluginHost {
288
285
  startPluginHost(logger: Logger, env: any, pluginDebug: PluginDebug) {
289
286
  let connected = true;
290
287
 
291
- if (this.packageJson.scrypted.runtime === 'python') {
292
- this.worker = new PythonRuntimeWorker(this.pluginId, {
293
- env,
294
- pluginDebug,
295
- });
296
- }
297
- else if (!this.packageJson.scrypted.runtime || this.packageJson.scrypted.runtime === 'node') {
298
- if (!process.env.SCRYPTED_SHARED_WORKER || (this.packageJson.optionalDependencies && Object.keys(this.packageJson.optionalDependencies).length)) {
299
- this.worker = new NodeForkWorker(this.scrypted.mainFilename, this.pluginId, {
300
- env,
301
- pluginDebug,
302
- });
303
- }
304
- else {
305
- this.worker = new NodeThreadWorker(this.scrypted.mainFilename, this.pluginId, {
306
- env,
307
- pluginDebug,
308
- });
309
- }
310
- }
311
- else {
288
+ let { runtime } = this.packageJson.scrypted;
289
+ runtime ||= 'node';
290
+
291
+ const workerHost = this.scrypted.pluginHosts.get(runtime);
292
+ if (!workerHost)
312
293
  throw new Error(`Unsupported Scrypted runtime: ${this.packageJson.scrypted.runtime}`);
313
- }
294
+
295
+ this.worker = workerHost(this.scrypted.mainFilename, this.pluginId, {
296
+ env,
297
+ pluginDebug,
298
+ });
314
299
 
315
300
  this.peer = new RpcPeer('host', this.pluginId, (message, reject, serializationContext) => {
316
301
  if (connected) {
@@ -191,10 +191,10 @@ export function startPluginRemote(mainFilename: string, pluginId: string, peerSe
191
191
  const module = require(name);
192
192
  return module;
193
193
  };
194
- const window: any = {};
195
- const exports: any = window;
196
- window.exports = exports;
197
- params.window = window;
194
+ // const window: any = {};
195
+ const exports: any = {};
196
+ // window.exports = exports;
197
+ // params.window = window;
198
198
  params.exports = exports;
199
199
 
200
200
  const entry = pluginReader('main.nodejs.js.map')
@@ -11,9 +11,9 @@ export class NodeForkWorker extends ChildProcessWorker {
11
11
 
12
12
  constructor(mainFilename: string, pluginId: string, options: RuntimeWorkerOptions) {
13
13
  super(pluginId, options);
14
-
15
- const {env, pluginDebug} = options;
16
-
14
+
15
+ const { env, pluginDebug } = options;
16
+
17
17
  const execArgv: string[] = process.execArgv.slice();
18
18
  if (pluginDebug) {
19
19
  execArgv.push(`--inspect=0.0.0.0:${pluginDebug.inspectPort}`);
@@ -1,6 +1,6 @@
1
1
  import { RpcMessage, RpcPeer } from "../../rpc";
2
2
  import { PluginDebug } from "../plugin-debug";
3
- import {Readable} from "stream";
3
+ import { Readable } from "stream";
4
4
  import net from "net";
5
5
 
6
6
  export interface RuntimeWorkerOptions {
package/src/runtime.ts CHANGED
@@ -40,6 +40,9 @@ import { ServiceControl } from './services/service-control';
40
40
  import { UsersService } from './services/users';
41
41
  import { getState, ScryptedStateManager, setState } from './state';
42
42
  import crypto from 'crypto';
43
+ import { RuntimeWorker, RuntimeWorkerOptions } from './plugin/runtime/runtime-worker';
44
+ import { PythonRuntimeWorker } from './plugin/runtime/python-worker';
45
+ import { NodeForkWorker } from './plugin/runtime/node-fork-worker';
43
46
 
44
47
  interface DeviceProxyPair {
45
48
  handler: PluginDeviceProxyHandler;
@@ -54,6 +57,8 @@ interface HttpPluginData {
54
57
  pluginDevice: PluginDevice
55
58
  }
56
59
 
60
+ export type RuntimeHost = (mainFilename: string, pluginId: string, options: RuntimeWorkerOptions) => RuntimeWorker;
61
+
57
62
  export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
58
63
  clusterId = crypto.randomBytes(3).toString('hex');
59
64
  clusterSecret = crypto.randomBytes(16).toString('hex');
@@ -83,12 +88,16 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
83
88
  corsControl = new CORSControl(this);
84
89
  addressSettings = new AddressSettings(this);
85
90
  usersService = new UsersService(this);
91
+ pluginHosts = new Map<string, RuntimeHost>();
86
92
 
87
93
  constructor(public mainFilename: string, datastore: Level, insecure: http.Server, secure: https.Server, app: express.Application) {
88
94
  super(app);
89
95
  this.datastore = datastore;
90
96
  this.app = app;
91
97
 
98
+ this.pluginHosts.set('python', (_, pluginId, options) => new PythonRuntimeWorker(pluginId, options));
99
+ this.pluginHosts.set('node', (mainFilename, pluginId, options) => new NodeForkWorker(mainFilename, pluginId, options));
100
+
92
101
  app.disable('x-powered-by');
93
102
 
94
103
  this.addMiddleware();
@@ -4,8 +4,15 @@ import process from 'process';
4
4
  import semver from 'semver';
5
5
  import { RPCResultError, startPeriodicGarbageCollection } from './rpc';
6
6
  import { PluginError } from './plugin/plugin-error';
7
+ import type { Runtime } from './scrypted-server-main';
7
8
 
8
- function start(mainFilename: string) {
9
+ export function isChildProcess() {
10
+ return process.argv[2] === 'child' || process.argv[2] === 'child-thread'
11
+ }
12
+
13
+ function start(mainFilename: string, options?: {
14
+ onRuntimeCreated?: (runtime: Runtime) => Promise<void>,
15
+ }) {
9
16
  if (!global.gc) {
10
17
  v8.setFlagsFromString('--expose_gc')
11
18
  global.gc = vm.runInNewContext("gc");
@@ -47,7 +54,7 @@ function start(mainFilename: string) {
47
54
  });
48
55
 
49
56
  const start = require('./scrypted-server-main').default;
50
- return start(mainFilename);
57
+ return start(mainFilename, options);
51
58
  }
52
59
  }
53
60
 
@@ -25,7 +25,7 @@ function start(mainFilename: string) {
25
25
  if (e)
26
26
  reject?.(e);
27
27
  }));
28
-
28
+
29
29
  peer.transportSafeArgumentTypes.add(Buffer.name);
30
30
  peer.addSerializer(net.Socket, net.Socket.name, new SidebandSocketSerializer());
31
31
  process.on('message', message => peer.handleMessage(message as RpcMessage));
@@ -27,6 +27,8 @@ import { setScryptedUserPassword } from './services/users';
27
27
  import { sleep } from './sleep';
28
28
  import { ONE_DAY_MILLISECONDS, UserToken } from './usertoken';
29
29
 
30
+ export type Runtime = ScryptedRuntime;
31
+
30
32
  if (!semver.gte(process.version, '16.0.0')) {
31
33
  throw new Error('"node" version out of date. Please update node to v16 or higher.')
32
34
  }
@@ -104,7 +106,9 @@ app.use(bodyParser.json())
104
106
  // parse some custom thing into a Buffer
105
107
  app.use(bodyParser.raw({ type: 'application/zip', limit: 100000000 }) as any)
106
108
 
107
- async function start(mainFilename: string) {
109
+ async function start(mainFilename: string, options?: {
110
+ onRuntimeCreated?: (runtime: ScryptedRuntime) => Promise<void>,
111
+ }) {
108
112
  const volumeDir = getScryptedVolume();
109
113
  mkdirp.sync(volumeDir);
110
114
  const dbPath = path.join(volumeDir, 'scrypted.db');
@@ -271,6 +275,7 @@ async function start(mainFilename: string) {
271
275
  });
272
276
 
273
277
  const scrypted = new ScryptedRuntime(mainFilename, db, insecure, secure, app);
278
+ await options?.onRuntimeCreated?.(scrypted);
274
279
  await scrypted.start();
275
280
 
276
281
  listenServerPort('SCRYPTED_SECURE_PORT', SCRYPTED_SECURE_PORT, secure);
@@ -1,9 +1,8 @@
1
1
  import child_process from 'child_process';
2
+ import net from 'net';
2
3
  import path from 'path';
3
4
  import type { Readable, Writable } from "stream";
4
5
  import { createDuplexRpcPeer } from '../src/rpc-serializer';
5
- import assert from 'assert';
6
- import net from 'net';
7
6
 
8
7
  async function main() {
9
8
  const server = net.createServer(client => {
@@ -21,12 +20,17 @@ async function main() {
21
20
  const rpcPeer = createDuplexRpcPeer('node', 'python', cp.stdio[3] as Readable, cp.stdio[4] as Writable);
22
21
 
23
22
  async function* test() {
24
- yield 1;
25
- yield 2;
26
- yield 3;
23
+ try {
24
+ for (let i = 0; ; i++) {
25
+ yield i;
26
+ }
27
+ }
28
+ finally {
29
+ console.log('closed');
30
+ }
27
31
  }
28
32
 
29
- rpcPeer.params['test'] = test();
33
+ rpcPeer.params['test'] = test;
30
34
 
31
35
  // const foo = await rpcPeer.getParam('foo');
32
36
  // assert.equal(foo, 3);
package/tsconfig.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "declaration": true,
3
4
  "module": "commonjs",
4
5
  "target": "esnext",
5
6
  "noImplicitAny": true,