@based/functions 1.2.2 → 2.0.1

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.
@@ -2,6 +2,7 @@ import { Context, HttpSession } from './context';
2
2
  import { BasedFunctionClient } from './client';
3
3
  import { BasedDataStream } from './stream';
4
4
  import { Authorize } from './auth';
5
+ import type { Required } from 'utility-types';
5
6
  export type ObservableUpdateFunction<K = any> = (data: K, checksum?: number, err?: any, cache?: Uint8Array, diff?: any, fromChecksum?: number, isDeflate?: boolean) => void;
6
7
  export type ObserveErrorListener = (err: any) => void;
7
8
  export type HttpHeaders = {
@@ -27,7 +28,7 @@ export type ChannelMessageFunctionInternal<K = any> = (message: K, err?: any) =>
27
28
  export type UninstallFunction = () => Promise<void>;
28
29
  type FunctionConfigShared = {
29
30
  /** Function name */
30
- name: string;
31
+ name?: string;
31
32
  /** In addition to the name, a function can have a custom path for HTTP requests.
32
33
  * For example: `path: 'my/custom/path'` will result in the function being
33
34
  * available with a request to `env.based.io/my/custom/path`
@@ -47,14 +48,41 @@ type FunctionConfigShared = {
47
48
  internalOnly?: boolean;
48
49
  /** Can hold extra information about a spec */
49
50
  data?: any;
50
- /** Unistall after idle, in ms */
51
+ /** Unistall after idle, in ms -1 indicates endless */
51
52
  uninstallAfterIdleTime?: number;
52
53
  /** Hook that fires on uninstall of the function e.g. to clean up database connections */
53
54
  uninstall?: UninstallFunction;
54
55
  /** Specific authorize for this function */
55
56
  authorize?: Authorize;
57
+ /** Relay allows functions to relay traffic to another `@based/server`
58
+ `Currently not supported for `stream`
59
+
60
+ ```js
61
+ new BasedServer({
62
+ clients: { events: BasedClient },
63
+ functions: {
64
+ specs:
65
+ somethingToRelay: {
66
+ relay: { client: 'events', target: 'hello' },
67
+ type: 'function'
68
+ })
69
+ }
70
+ }
71
+ })
72
+ ```
73
+ */
74
+ relay?: {
75
+ client: string;
76
+ target?: string;
77
+ };
78
+ /** Function version */
79
+ version?: number;
80
+ /** Used inernaly to check if a function is ready to uninstall */
81
+ timeoutCounter?: number;
56
82
  };
57
- export type BasedFunctionConfig = ({
83
+ type FunctionConfigSharedComplete = Required<FunctionConfigShared, 'maxPayloadSize' | 'rateLimitTokens' | 'version' | 'name'>;
84
+ export type BasedFunctionTypes = 'channel' | 'query' | 'function' | 'stream';
85
+ type BasedChannelFunctionConfig = {
58
86
  /** Function type `channel, function, query, stream, authorize` */
59
87
  type: 'channel';
60
88
  /** Channel subscriber
@@ -81,32 +109,47 @@ export type BasedFunctionConfig = ({
81
109
  publisher?: BasedChannelPublishFunction;
82
110
  /** Makes only the publisher public */
83
111
  publicPublisher?: boolean;
84
- name: string;
85
112
  /** How long should the channel subscriber remain active after all subscribers are gone, in ms */
86
113
  closeAfterIdleTime?: number;
87
- } & FunctionConfigShared) | ({
88
- /** Function type `channel, function, query, stream, authorize` */
114
+ /** Only for Publisher */
115
+ httpResponse?: HttpResponse;
116
+ };
117
+ type BasedCallFunctionConfig = {
118
+ /** Function type `channel, function, query, stream` */
89
119
  type: 'function';
90
- function: BasedFunction;
91
- name: string;
120
+ fn: BasedFunction;
92
121
  httpResponse?: HttpResponse;
93
- } & FunctionConfigShared) | ({
94
- /** Function type `channel, function, query, stream, authorize` */
122
+ };
123
+ type BasedQueryFunctionConfig = {
124
+ /** Function type `channel, function, query, stream` */
95
125
  type: 'query';
96
- function: BasedQueryFunction;
97
- name: string;
126
+ fn: BasedQueryFunction;
98
127
  httpResponse?: HttpResponse;
99
128
  /** How long should the query function remain active after all subscribers are gone, in ms */
100
129
  closeAfterIdleTime?: number;
101
- } & FunctionConfigShared) | ({
102
- /** Function type `channel, function, query, stream, authorize` */
130
+ };
131
+ type BasedStreamFunctionConfig = {
132
+ /** Function type `channel, function, query, stream` */
103
133
  type: 'stream';
104
- function: BasedStreamFunction;
105
- name: string;
106
- } & FunctionConfigShared) | {
107
- /** Function type `channel, function, query, stream, authorize` */
134
+ fn: BasedStreamFunction;
135
+ };
136
+ export type BasedFunctionConfig<T extends BasedFunctionTypes = BasedFunctionTypes> = T extends 'channel' ? BasedChannelFunctionConfig & FunctionConfigShared : T extends 'function' ? BasedCallFunctionConfig & FunctionConfigShared : T extends 'query' ? BasedQueryFunctionConfig & FunctionConfigShared : T extends 'stream' ? BasedStreamFunctionConfig & FunctionConfigShared : (BasedChannelFunctionConfig & FunctionConfigShared) | (BasedCallFunctionConfig & FunctionConfigShared) | (BasedQueryFunctionConfig & FunctionConfigShared) | (BasedStreamFunctionConfig & FunctionConfigShared);
137
+ export type BasedFunctionConfigComplete<T extends BasedFunctionTypes = BasedFunctionTypes> = T extends 'channel' ? BasedChannelFunctionConfig & FunctionConfigSharedComplete : T extends 'function' ? BasedCallFunctionConfig & FunctionConfigSharedComplete : T extends 'query' ? BasedQueryFunctionConfig & FunctionConfigSharedComplete : T extends 'stream' ? BasedStreamFunctionConfig & FunctionConfigSharedComplete : (BasedChannelFunctionConfig & FunctionConfigSharedComplete) | (BasedCallFunctionConfig & FunctionConfigSharedComplete) | (BasedQueryFunctionConfig & FunctionConfigSharedComplete) | (BasedStreamFunctionConfig & FunctionConfigSharedComplete);
138
+ export type BasedAuthorizeFunctionConfig = {
139
+ /** Function type `authorize` */
108
140
  type: 'authorize';
109
141
  function: Authorize;
110
- name: string;
142
+ };
143
+ export type BasedRoute<T extends BasedFunctionTypes = BasedFunctionTypes, R extends keyof BasedFunctionConfig = 'type' | 'name'> = Required<Partial<BasedFunctionConfig<T>>, R>;
144
+ export type BasedRouteComplete<T extends BasedFunctionTypes = BasedFunctionTypes> = Required<Partial<BasedFunctionConfig<T>>, 'type' | 'name' | 'maxPayloadSize' | 'rateLimitTokens'>;
145
+ export declare function isBasedRoute<T extends BasedFunctionTypes>(type: T, route: any): route is BasedRoute<T>;
146
+ export declare function isAnyBasedRoute(route: any): route is BasedRoute;
147
+ export declare function isBasedFunctionConfig<T extends BasedFunctionTypes>(type: T, config: any): config is BasedFunctionConfig<T>;
148
+ export declare function isAnyBasedFunctionConfig(config: any): config is BasedFunctionConfig;
149
+ export type BasedRoutes = {
150
+ [name: string]: BasedRoute<BasedFunctionTypes, 'type'>;
151
+ };
152
+ export type BasedFunctionConfigs = {
153
+ [name: string]: BasedFunctionConfig<BasedFunctionTypes>;
111
154
  };
112
155
  export {};
package/dist/functions.js CHANGED
@@ -1,3 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAnyBasedFunctionConfig = exports.isBasedFunctionConfig = exports.isAnyBasedRoute = exports.isBasedRoute = void 0;
4
+ function isBasedRoute(type, route) {
5
+ return (route &&
6
+ typeof route === 'object' &&
7
+ route.type === type &&
8
+ typeof route.name === 'string');
9
+ }
10
+ exports.isBasedRoute = isBasedRoute;
11
+ function isAnyBasedRoute(route) {
12
+ return (route &&
13
+ typeof route === 'object' &&
14
+ (route.type === 'channel' ||
15
+ route.type === 'query' ||
16
+ route.type === 'function' ||
17
+ route.type === 'stream') &&
18
+ typeof route.name === 'string');
19
+ }
20
+ exports.isAnyBasedRoute = isAnyBasedRoute;
21
+ function isBasedFunctionConfig(type, config) {
22
+ return isBasedRoute(type, config);
23
+ }
24
+ exports.isBasedFunctionConfig = isBasedFunctionConfig;
25
+ function isAnyBasedFunctionConfig(config) {
26
+ return isAnyBasedRoute(config);
27
+ }
28
+ exports.isAnyBasedFunctionConfig = isAnyBasedFunctionConfig;
3
29
  //# sourceMappingURL=functions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"functions.js","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":";;;AAuQA,SAAgB,YAAY,CAC1B,IAAO,EACP,KAAU;IAEV,OAAO,CACL,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,IAAI,KAAK,IAAI;QACnB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAC/B,CAAA;AACH,CAAC;AAVD,oCAUC;AAED,SAAgB,eAAe,CAAC,KAAU;IACxC,OAAO,CACL,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YACvB,KAAK,CAAC,IAAI,KAAK,OAAO;YACtB,KAAK,CAAC,IAAI,KAAK,UAAU;YACzB,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAC/B,CAAA;AACH,CAAC;AAVD,0CAUC;AAED,SAAgB,qBAAqB,CACnC,IAAO,EACP,MAAW;IAEX,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACnC,CAAC;AALD,sDAKC;AAED,SAAgB,wBAAwB,CACtC,MAAW;IAEX,OAAO,eAAe,CAAC,MAAM,CAAC,CAAA;AAChC,CAAC;AAJD,4DAIC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/functions",
3
- "version": "1.2.2",
3
+ "version": "2.0.1",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -10,7 +10,8 @@
10
10
  },
11
11
  "sideEffects": false,
12
12
  "dependencies": {
13
- "@saulx/utils": "^3.2.1"
13
+ "utility-types": "^3.10.0",
14
+ "@saulx/utils": "^3.2.2"
14
15
  },
15
16
  "devDependencies": {
16
17
  "ts-node": "10.9.1",
package/src/functions.ts CHANGED
@@ -2,6 +2,7 @@ import { Context, HttpSession } from './context'
2
2
  import { BasedFunctionClient } from './client'
3
3
  import { BasedDataStream } from './stream'
4
4
  import { Authorize } from './auth'
5
+ import type { Required } from 'utility-types'
5
6
 
6
7
  export type ObservableUpdateFunction<K = any> = (
7
8
  data: K,
@@ -92,9 +93,10 @@ export type ChannelMessageFunctionInternal<K = any> = (
92
93
 
93
94
  export type UninstallFunction = () => Promise<void>
94
95
 
96
+ // ------------ Config -------------------
95
97
  type FunctionConfigShared = {
96
98
  /** Function name */
97
- name: string
99
+ name?: string
98
100
  /** In addition to the name, a function can have a custom path for HTTP requests.
99
101
  * For example: `path: 'my/custom/path'` will result in the function being
100
102
  * available with a request to `env.based.io/my/custom/path`
@@ -114,71 +116,192 @@ type FunctionConfigShared = {
114
116
  internalOnly?: boolean
115
117
  /** Can hold extra information about a spec */
116
118
  data?: any
117
- /** Unistall after idle, in ms */
119
+ /** Unistall after idle, in ms -1 indicates endless */
118
120
  uninstallAfterIdleTime?: number
119
121
  /** Hook that fires on uninstall of the function e.g. to clean up database connections */
120
122
  uninstall?: UninstallFunction
121
123
  /** Specific authorize for this function */
122
124
  authorize?: Authorize
125
+ /** Relay allows functions to relay traffic to another `@based/server`
126
+ `Currently not supported for `stream`
127
+
128
+ ```js
129
+ new BasedServer({
130
+ clients: { events: BasedClient },
131
+ functions: {
132
+ specs:
133
+ somethingToRelay: {
134
+ relay: { client: 'events', target: 'hello' },
135
+ type: 'function'
136
+ })
137
+ }
138
+ }
139
+ })
140
+ ```
141
+ */
142
+ relay?: {
143
+ client: string
144
+ target?: string
145
+ }
146
+ /** Function version */
147
+ version?: number
148
+ /** Used inernaly to check if a function is ready to uninstall */
149
+ timeoutCounter?: number
123
150
  }
124
151
 
125
- export type BasedFunctionConfig =
126
- | ({
127
- /** Function type `channel, function, query, stream, authorize` */
128
- type: 'channel'
129
- /** Channel subscriber
130
-
131
- ```js
132
- const subscribe = (based, payload, id, update) => {
133
- let cnt = 0
134
- const interval = setInterval(() => {
135
- update(++cnt)
136
- })
137
- return () => clearInterval(cnt)
138
- }
139
- ```
140
- */
141
- subscriber?: BasedChannelFunction
142
- /** Channel publisher
143
-
144
- ```js
145
- const publisher = (based, payload, msg, id) => {
146
- publishToChannel(id, msg)
147
- }
148
- ```
149
- */
150
- publisher?: BasedChannelPublishFunction
151
- /** Makes only the publisher public */
152
- publicPublisher?: boolean
153
- name: string
154
- /** How long should the channel subscriber remain active after all subscribers are gone, in ms */
155
- closeAfterIdleTime?: number
156
- } & FunctionConfigShared)
157
- | ({
158
- /** Function type `channel, function, query, stream, authorize` */
159
- type: 'function'
160
- function: BasedFunction
161
- name: string
162
- httpResponse?: HttpResponse
163
- } & FunctionConfigShared)
164
- | ({
165
- /** Function type `channel, function, query, stream, authorize` */
166
- type: 'query'
167
- function: BasedQueryFunction
168
- name: string
169
- httpResponse?: HttpResponse
170
- /** How long should the query function remain active after all subscribers are gone, in ms */
171
- closeAfterIdleTime?: number
172
- } & FunctionConfigShared)
173
- | ({
174
- /** Function type `channel, function, query, stream, authorize` */
175
- type: 'stream'
176
- function: BasedStreamFunction
177
- name: string
178
- } & FunctionConfigShared)
179
- | {
180
- /** Function type `channel, function, query, stream, authorize` */
181
- type: 'authorize'
182
- function: Authorize
183
- name: string
184
- }
152
+ type FunctionConfigSharedComplete = Required<
153
+ FunctionConfigShared,
154
+ 'maxPayloadSize' | 'rateLimitTokens' | 'version' | 'name'
155
+ >
156
+
157
+ export type BasedFunctionTypes = 'channel' | 'query' | 'function' | 'stream'
158
+
159
+ type BasedChannelFunctionConfig = {
160
+ /** Function type `channel, function, query, stream, authorize` */
161
+ type: 'channel'
162
+ /** Channel subscriber
163
+
164
+ ```js
165
+ const subscribe = (based, payload, id, update) => {
166
+ let cnt = 0
167
+ const interval = setInterval(() => {
168
+ update(++cnt)
169
+ })
170
+ return () => clearInterval(cnt)
171
+ }
172
+ ```
173
+ */
174
+ subscriber?: BasedChannelFunction
175
+ /** Channel publisher
176
+
177
+ ```js
178
+ const publisher = (based, payload, msg, id) => {
179
+ publishToChannel(id, msg)
180
+ }
181
+ ```
182
+ */
183
+ publisher?: BasedChannelPublishFunction
184
+ /** Makes only the publisher public */
185
+ publicPublisher?: boolean
186
+ /** How long should the channel subscriber remain active after all subscribers are gone, in ms */
187
+ closeAfterIdleTime?: number
188
+ /** Only for Publisher */
189
+ httpResponse?: HttpResponse
190
+ }
191
+
192
+ type BasedCallFunctionConfig = {
193
+ /** Function type `channel, function, query, stream` */
194
+ type: 'function'
195
+ fn: BasedFunction
196
+ httpResponse?: HttpResponse
197
+ }
198
+
199
+ type BasedQueryFunctionConfig = {
200
+ /** Function type `channel, function, query, stream` */
201
+ type: 'query'
202
+ fn: BasedQueryFunction
203
+ httpResponse?: HttpResponse
204
+ /** How long should the query function remain active after all subscribers are gone, in ms */
205
+ closeAfterIdleTime?: number
206
+ }
207
+
208
+ type BasedStreamFunctionConfig = {
209
+ /** Function type `channel, function, query, stream` */
210
+ type: 'stream'
211
+ fn: BasedStreamFunction
212
+ }
213
+
214
+ export type BasedFunctionConfig<
215
+ T extends BasedFunctionTypes = BasedFunctionTypes
216
+ > = T extends 'channel'
217
+ ? BasedChannelFunctionConfig & FunctionConfigShared
218
+ : T extends 'function'
219
+ ? BasedCallFunctionConfig & FunctionConfigShared
220
+ : T extends 'query'
221
+ ? BasedQueryFunctionConfig & FunctionConfigShared
222
+ : T extends 'stream'
223
+ ? BasedStreamFunctionConfig & FunctionConfigShared
224
+ :
225
+ | (BasedChannelFunctionConfig & FunctionConfigShared)
226
+ | (BasedCallFunctionConfig & FunctionConfigShared)
227
+ | (BasedQueryFunctionConfig & FunctionConfigShared)
228
+ | (BasedStreamFunctionConfig & FunctionConfigShared)
229
+
230
+ export type BasedFunctionConfigComplete<
231
+ T extends BasedFunctionTypes = BasedFunctionTypes
232
+ > = T extends 'channel'
233
+ ? BasedChannelFunctionConfig & FunctionConfigSharedComplete
234
+ : T extends 'function'
235
+ ? BasedCallFunctionConfig & FunctionConfigSharedComplete
236
+ : T extends 'query'
237
+ ? BasedQueryFunctionConfig & FunctionConfigSharedComplete
238
+ : T extends 'stream'
239
+ ? BasedStreamFunctionConfig & FunctionConfigSharedComplete
240
+ :
241
+ | (BasedChannelFunctionConfig & FunctionConfigSharedComplete)
242
+ | (BasedCallFunctionConfig & FunctionConfigSharedComplete)
243
+ | (BasedQueryFunctionConfig & FunctionConfigSharedComplete)
244
+ | (BasedStreamFunctionConfig & FunctionConfigSharedComplete)
245
+
246
+ export type BasedAuthorizeFunctionConfig = {
247
+ /** Function type `authorize` */
248
+ type: 'authorize'
249
+ function: Authorize
250
+ }
251
+
252
+ export type BasedRoute<
253
+ T extends BasedFunctionTypes = BasedFunctionTypes,
254
+ R extends keyof BasedFunctionConfig = 'type' | 'name'
255
+ > = Required<Partial<BasedFunctionConfig<T>>, R>
256
+
257
+ export type BasedRouteComplete<
258
+ T extends BasedFunctionTypes = BasedFunctionTypes
259
+ > = Required<
260
+ Partial<BasedFunctionConfig<T>>,
261
+ 'type' | 'name' | 'maxPayloadSize' | 'rateLimitTokens'
262
+ >
263
+
264
+ export function isBasedRoute<T extends BasedFunctionTypes>(
265
+ type: T,
266
+ route: any
267
+ ): route is BasedRoute<T> {
268
+ return (
269
+ route &&
270
+ typeof route === 'object' &&
271
+ route.type === type &&
272
+ typeof route.name === 'string'
273
+ )
274
+ }
275
+
276
+ export function isAnyBasedRoute(route: any): route is BasedRoute {
277
+ return (
278
+ route &&
279
+ typeof route === 'object' &&
280
+ (route.type === 'channel' ||
281
+ route.type === 'query' ||
282
+ route.type === 'function' ||
283
+ route.type === 'stream') &&
284
+ typeof route.name === 'string'
285
+ )
286
+ }
287
+
288
+ export function isBasedFunctionConfig<T extends BasedFunctionTypes>(
289
+ type: T,
290
+ config: any
291
+ ): config is BasedFunctionConfig<T> {
292
+ return isBasedRoute(type, config)
293
+ }
294
+
295
+ export function isAnyBasedFunctionConfig(
296
+ config: any
297
+ ): config is BasedFunctionConfig {
298
+ return isAnyBasedRoute(config)
299
+ }
300
+
301
+ export type BasedRoutes = {
302
+ [name: string]: BasedRoute<BasedFunctionTypes, 'type'>
303
+ }
304
+
305
+ export type BasedFunctionConfigs = {
306
+ [name: string]: BasedFunctionConfig<BasedFunctionTypes>
307
+ }