@based/functions 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/auth.d.ts +4 -4
- package/dist/channel.d.ts +5 -0
- package/dist/channel.js +7 -0
- package/dist/channel.js.map +1 -0
- package/dist/client.d.ts +5 -2
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +28 -11
- package/dist/context.js +16 -2
- package/dist/context.js.map +1 -1
- package/dist/functions.d.ts +18 -13
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/query.d.ts +4 -4
- package/dist/stream.d.ts +39 -0
- package/dist/stream.js +63 -0
- package/dist/stream.js.map +1 -0
- package/dist/uws.d.ts +459 -131
- package/package.json +4 -4
- package/src/auth.ts +1 -1
- package/src/channel.ts +10 -0
- package/src/client.ts +14 -2
- package/src/context.ts +45 -8
- package/src/functions.ts +48 -12
- package/src/index.ts +2 -0
- package/src/query.ts +4 -4
- package/src/stream.ts +95 -0
- package/src/uws.d.ts +469 -0
- package/.turbo/turbo-build.log +0 -4
- package/dist/uws.js +0 -3
- package/dist/uws.js.map +0 -1
- package/src/uws.ts +0 -197
package/src/channel.ts
ADDED
package/src/client.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { AuthState } from './auth'
|
|
2
|
+
import { BasedChannel } from './channel'
|
|
2
3
|
import { Context } from './context'
|
|
3
4
|
import { BasedQuery } from './query'
|
|
5
|
+
import { StreamFunctionOpts } from './stream'
|
|
4
6
|
|
|
7
|
+
// TODO: this is the place where we will add extra specifications
|
|
5
8
|
export abstract class BasedFunctionClient {
|
|
6
9
|
server: any
|
|
7
10
|
|
|
@@ -9,9 +12,18 @@ export abstract class BasedFunctionClient {
|
|
|
9
12
|
|
|
10
13
|
abstract query(name: string, payload?: any): BasedQuery
|
|
11
14
|
|
|
12
|
-
abstract
|
|
15
|
+
abstract channel(name: string, payload?: any): BasedChannel
|
|
16
|
+
|
|
17
|
+
abstract stream(
|
|
18
|
+
name: string,
|
|
19
|
+
payload: StreamFunctionOpts,
|
|
20
|
+
ctx?: Context
|
|
21
|
+
): Promise<any>
|
|
13
22
|
|
|
14
23
|
abstract sendAuthState(ctx: Context, authState: AuthState): void
|
|
15
24
|
|
|
16
|
-
abstract renewAuthState(
|
|
25
|
+
abstract renewAuthState(
|
|
26
|
+
ctx: Context,
|
|
27
|
+
authState?: AuthState
|
|
28
|
+
): Promise<AuthState>
|
|
17
29
|
}
|
package/src/context.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { parseQuery } from '@saulx/utils'
|
|
|
4
4
|
import { BasedFunctionClient } from './client'
|
|
5
5
|
|
|
6
6
|
export type WebSocketSession = {
|
|
7
|
-
// State can be used for
|
|
7
|
+
// State can be used for anything - for us the based class instance
|
|
8
8
|
state?: any
|
|
9
9
|
query: string
|
|
10
10
|
ua: string
|
|
@@ -13,18 +13,26 @@ export type WebSocketSession = {
|
|
|
13
13
|
method: string
|
|
14
14
|
authState: AuthState
|
|
15
15
|
obs: Set<number>
|
|
16
|
-
unauthorizedObs
|
|
16
|
+
unauthorizedObs?: Set<{
|
|
17
17
|
id: number
|
|
18
18
|
checksum: number
|
|
19
19
|
name: string
|
|
20
20
|
payload: any
|
|
21
21
|
}>
|
|
22
|
+
unauthorizedChannels?: Set<{
|
|
23
|
+
id: number
|
|
24
|
+
name: string
|
|
25
|
+
payload: any
|
|
26
|
+
}>
|
|
22
27
|
// Optimization so we dont need to keep track of websockets outside of uws
|
|
23
28
|
c?: Context<WebSocketSession>
|
|
24
|
-
|
|
29
|
+
ws?: BasedWebSocket
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type BasedWebSocket = WebSocket<WebSocketSession>
|
|
25
33
|
|
|
26
34
|
export type HttpSession = {
|
|
27
|
-
// State can be used for
|
|
35
|
+
// State can be used for anything - for us the based class instance
|
|
28
36
|
state?: any
|
|
29
37
|
res: HttpResponse
|
|
30
38
|
req: HttpRequest
|
|
@@ -47,7 +55,13 @@ export type HttpSession = {
|
|
|
47
55
|
export type InternalSessionObservable = {
|
|
48
56
|
id: number
|
|
49
57
|
name: string
|
|
50
|
-
type: '
|
|
58
|
+
type: 'query'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type InternalSessionChannel = {
|
|
62
|
+
id: number
|
|
63
|
+
name: string
|
|
64
|
+
type: 'channel'
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
export type InternalSessionClient = {
|
|
@@ -56,7 +70,10 @@ export type InternalSessionClient = {
|
|
|
56
70
|
}
|
|
57
71
|
|
|
58
72
|
// Internal session for internal functions
|
|
59
|
-
export type InternalSession =
|
|
73
|
+
export type InternalSession =
|
|
74
|
+
| InternalSessionClient
|
|
75
|
+
| InternalSessionObservable
|
|
76
|
+
| InternalSessionChannel
|
|
60
77
|
|
|
61
78
|
// used for minimal security errors (e.g. rate limit)
|
|
62
79
|
export type MinimalExternalSession = {
|
|
@@ -64,11 +81,15 @@ export type MinimalExternalSession = {
|
|
|
64
81
|
ip: string
|
|
65
82
|
}
|
|
66
83
|
|
|
67
|
-
export type Session =
|
|
84
|
+
export type Session = (
|
|
68
85
|
| WebSocketSession
|
|
69
86
|
| HttpSession
|
|
70
87
|
| InternalSession
|
|
71
88
|
| MinimalExternalSession
|
|
89
|
+
) & {
|
|
90
|
+
/** Only available in Ws and Http contexts */
|
|
91
|
+
authState?: AuthState
|
|
92
|
+
}
|
|
72
93
|
|
|
73
94
|
export type Context<S extends Session = Session> = {
|
|
74
95
|
session?: S
|
|
@@ -92,8 +113,24 @@ export const isWsContext = (
|
|
|
92
113
|
return false
|
|
93
114
|
}
|
|
94
115
|
|
|
116
|
+
export const isClientContext = (
|
|
117
|
+
ctx: Context<Session>
|
|
118
|
+
): ctx is Context<WebSocketSession | HttpSession> => {
|
|
119
|
+
if (ctx.session && (isWsSession(ctx.session) || isHttpSession(ctx.session))) {
|
|
120
|
+
return true
|
|
121
|
+
}
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const isHttpSession = (session: Session): session is HttpSession => {
|
|
126
|
+
if ('res' in session) {
|
|
127
|
+
return true
|
|
128
|
+
}
|
|
129
|
+
return false
|
|
130
|
+
}
|
|
131
|
+
|
|
95
132
|
export const isWsSession = (session: Session): session is WebSocketSession => {
|
|
96
|
-
if (
|
|
133
|
+
if ('send' in session) {
|
|
97
134
|
return true
|
|
98
135
|
}
|
|
99
136
|
return false
|
package/src/functions.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context, HttpSession } from './context'
|
|
2
2
|
import { BasedFunctionClient } from './client'
|
|
3
|
-
import {
|
|
3
|
+
import { BasedDataStream } from './stream'
|
|
4
4
|
|
|
5
5
|
export type ObservableUpdateFunction<K = any> = {
|
|
6
6
|
(
|
|
@@ -19,11 +19,23 @@ export type ObservableUpdateFunction<K = any> = {
|
|
|
19
19
|
// TODO: use error package
|
|
20
20
|
export type ObserveErrorListener = (err: any) => void
|
|
21
21
|
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
export type HttpHeaders = {
|
|
23
|
+
[header: string]: number | string | (string | number)[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type SendHttpResponse = (
|
|
27
|
+
responseData: any,
|
|
28
|
+
headers?: HttpHeaders,
|
|
29
|
+
status?: string | number
|
|
30
|
+
) => void
|
|
31
|
+
|
|
32
|
+
export type HttpResponse<P = any, K = any> = (
|
|
33
|
+
based: BasedFunctionClient,
|
|
34
|
+
payload: P,
|
|
35
|
+
responseData: K,
|
|
36
|
+
send: SendHttpResponse,
|
|
37
|
+
ctx: Context<HttpSession>
|
|
38
|
+
) => Promise<void>
|
|
27
39
|
|
|
28
40
|
export type BasedFunction<P = any, K = any> = (
|
|
29
41
|
based: BasedFunctionClient,
|
|
@@ -35,10 +47,7 @@ export type StreamPayload<P = any> = {
|
|
|
35
47
|
payload?: P
|
|
36
48
|
mimeType: string
|
|
37
49
|
size: number
|
|
38
|
-
stream:
|
|
39
|
-
size: number
|
|
40
|
-
receivedBytes: number
|
|
41
|
-
}
|
|
50
|
+
stream: BasedDataStream
|
|
42
51
|
fileName?: string
|
|
43
52
|
extension?: string
|
|
44
53
|
}
|
|
@@ -52,10 +61,37 @@ export type BasedQueryFunction<P = any, K = any> =
|
|
|
52
61
|
| ((
|
|
53
62
|
based: BasedFunctionClient,
|
|
54
63
|
payload: P,
|
|
55
|
-
update: ObservableUpdateFunction<K
|
|
64
|
+
update: ObservableUpdateFunction<K>,
|
|
65
|
+
error: ObserveErrorListener
|
|
56
66
|
) => Promise<() => void>)
|
|
57
67
|
| ((
|
|
58
68
|
based: BasedFunctionClient,
|
|
59
69
|
payload: P,
|
|
60
|
-
update: ObservableUpdateFunction<K
|
|
70
|
+
update: ObservableUpdateFunction<K>,
|
|
71
|
+
error: ObserveErrorListener
|
|
61
72
|
) => () => void)
|
|
73
|
+
|
|
74
|
+
export type BasedChannelFunction<P = any, K = any> = (
|
|
75
|
+
based: BasedFunctionClient,
|
|
76
|
+
payload: P,
|
|
77
|
+
id: number,
|
|
78
|
+
update: ChannelMessageFunction<K>,
|
|
79
|
+
error: (err?: any) => void
|
|
80
|
+
) => () => void
|
|
81
|
+
|
|
82
|
+
export type BasedChannelPublishFunction<P = any, K = any> = (
|
|
83
|
+
based: BasedFunctionClient,
|
|
84
|
+
payload: P,
|
|
85
|
+
message: K,
|
|
86
|
+
id: number,
|
|
87
|
+
ctx: Context
|
|
88
|
+
) => void
|
|
89
|
+
|
|
90
|
+
export type ChannelMessageFunction<K = any> = (message: K) => void
|
|
91
|
+
|
|
92
|
+
export type ChannelMessageFunctionInternal<K = any> = (
|
|
93
|
+
message: K,
|
|
94
|
+
err?: any
|
|
95
|
+
) => void
|
|
96
|
+
|
|
97
|
+
export type UninstallFunction = () => Promise<void>
|
package/src/index.ts
CHANGED
package/src/query.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ObservableUpdateFunction, ObserveErrorListener } from './functions'
|
|
2
2
|
|
|
3
|
-
export abstract class BasedQuery {
|
|
3
|
+
export abstract class BasedQuery<K = any> {
|
|
4
4
|
abstract subscribe(
|
|
5
|
-
onData: ObservableUpdateFunction
|
|
5
|
+
onData: ObservableUpdateFunction<K>,
|
|
6
6
|
onError?: ObserveErrorListener
|
|
7
7
|
): () => void
|
|
8
8
|
|
|
9
9
|
abstract getWhen(
|
|
10
|
-
condition: (data:
|
|
10
|
+
condition: (data: K, checksum: number) => boolean
|
|
11
11
|
): Promise<any>
|
|
12
12
|
|
|
13
|
-
abstract get(): Promise<
|
|
13
|
+
abstract get(): Promise<K>
|
|
14
14
|
}
|
package/src/stream.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Duplex, Readable } from 'stream'
|
|
2
|
+
import util from 'node:util'
|
|
3
|
+
|
|
4
|
+
// prob want to move this to based functions
|
|
5
|
+
export class BasedDataStream extends Duplex {
|
|
6
|
+
public size: number = 0
|
|
7
|
+
public receivedBytes: number = 0
|
|
8
|
+
public progessTimer: NodeJS.Timeout
|
|
9
|
+
|
|
10
|
+
constructor(size: number) {
|
|
11
|
+
super()
|
|
12
|
+
this.size = size
|
|
13
|
+
this.emit('progress', 0)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_read() {}
|
|
17
|
+
|
|
18
|
+
_write(chunk, encoding, callback) {
|
|
19
|
+
this.receivedBytes += chunk.byteLength
|
|
20
|
+
if (this.size && this.size > 20000) {
|
|
21
|
+
if (!this.progessTimer) {
|
|
22
|
+
this.progessTimer = setTimeout(() => {
|
|
23
|
+
const progress = this.receivedBytes / this.size
|
|
24
|
+
this.emit('progress', progress)
|
|
25
|
+
this.progessTimer = null
|
|
26
|
+
}, 200)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
this.push(Buffer.from(chunk, encoding))
|
|
30
|
+
callback()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_final() {
|
|
34
|
+
if (!this.size) {
|
|
35
|
+
this.size = this.receivedBytes
|
|
36
|
+
}
|
|
37
|
+
this.receivedBytes = this.size
|
|
38
|
+
if (this.progessTimer) {
|
|
39
|
+
clearTimeout(this.progessTimer)
|
|
40
|
+
this.progessTimer = null
|
|
41
|
+
}
|
|
42
|
+
this.emit('progress', 1)
|
|
43
|
+
this.push(null)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
[util.inspect.custom]() {
|
|
47
|
+
if (this.size) {
|
|
48
|
+
const rb =
|
|
49
|
+
this.receivedBytes < 1000
|
|
50
|
+
? Math.round(this.receivedBytes / 1024) + 'kb'
|
|
51
|
+
: Math.round(this.receivedBytes / 1024 / 1024) + 'mb'
|
|
52
|
+
|
|
53
|
+
return `[BasedStream ${~~(
|
|
54
|
+
(this.receivedBytes / this.size) *
|
|
55
|
+
100
|
|
56
|
+
)}% ${rb}]`
|
|
57
|
+
} else {
|
|
58
|
+
return `[BasedStream]`
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// maybe make a type pkg
|
|
64
|
+
export type StreamFunctionContents<F = Buffer | ArrayBuffer | string> = {
|
|
65
|
+
contents: F
|
|
66
|
+
payload?: any
|
|
67
|
+
mimeType?: string
|
|
68
|
+
fileName?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type StreamFunctionStream =
|
|
72
|
+
| {
|
|
73
|
+
contents: Readable | Duplex
|
|
74
|
+
payload?: any
|
|
75
|
+
size: number
|
|
76
|
+
mimeType?: string
|
|
77
|
+
fileName?: string
|
|
78
|
+
extension?: string
|
|
79
|
+
}
|
|
80
|
+
| {
|
|
81
|
+
contents: BasedDataStream
|
|
82
|
+
payload?: any
|
|
83
|
+
size?: number
|
|
84
|
+
mimeType?: string
|
|
85
|
+
fileName?: string
|
|
86
|
+
extension?: string
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type StreamFunctionOpts = StreamFunctionContents | StreamFunctionStream
|
|
90
|
+
|
|
91
|
+
export const isStreamFunctionOpts = (
|
|
92
|
+
opts: StreamFunctionContents | StreamFunctionStream
|
|
93
|
+
): opts is StreamFunctionStream => {
|
|
94
|
+
return opts.contents instanceof Duplex || opts.contents instanceof Readable
|
|
95
|
+
}
|