vovk 0.0.0 → 0.1.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.
package/types.d.ts ADDED
@@ -0,0 +1,140 @@
1
+ import type { NextRequest } from 'next/server';
2
+ export type _KnownAny = any;
3
+ export type _ErrorResponseBody = {
4
+ statusCode: _HttpStatus;
5
+ message: string;
6
+ isError: true;
7
+ };
8
+ export type _HandlerMetadata = {
9
+ path: string;
10
+ httpMethod: _HttpMethod;
11
+ clientValidators?: {
12
+ query?: _KnownAny;
13
+ body?: _KnownAny;
14
+ };
15
+ };
16
+ export type _VovkControllerMetadata = {
17
+ controllerName: string;
18
+ _prefix?: string;
19
+ _handlers: Record<string, _HandlerMetadata>;
20
+ };
21
+ export type _HandlerMetadataJson = {
22
+ path: string;
23
+ httpMethod: string;
24
+ clientValidators?: {
25
+ query?: _KnownAny;
26
+ body?: _KnownAny;
27
+ };
28
+ };
29
+ export type _VovkControllerMetadataJson = {
30
+ controllerName: string;
31
+ _prefix?: string;
32
+ _handlers: Record<string, _HandlerMetadataJson>;
33
+ };
34
+ export type _VovkWorkerMetadata = {
35
+ workerName: string;
36
+ _handlers: Record<string, {
37
+ isGenerator?: true;
38
+ }>;
39
+ };
40
+ export type _VovkControllerInternal = _VovkControllerMetadata & {
41
+ _activated?: true;
42
+ _onError?: (err: Error) => void;
43
+ };
44
+ export type _VovkController = Function & _VovkControllerInternal & {
45
+ [key: string]: unknown;
46
+ };
47
+ export type _VovkWorker = Function & _VovkWorkerMetadata & {
48
+ [key: string]: unknown;
49
+ };
50
+ export type _RouteHandler = (req: NextRequest, params: Record<string, string>) => Response | Promise<Response>;
51
+ export interface _VovkRequest<BODY = undefined, QUERY extends Record<string, string> | undefined = undefined> extends Omit<NextRequest, 'json' | 'nextUrl'> {
52
+ json: () => Promise<BODY>;
53
+ nextUrl: Omit<NextRequest['nextUrl'], 'searchParams'> & {
54
+ searchParams: Omit<NextRequest['nextUrl']['searchParams'], 'get'> & {
55
+ get: <KEY extends keyof QUERY>(key: KEY) => QUERY[KEY];
56
+ readonly __queryType: QUERY;
57
+ };
58
+ };
59
+ }
60
+ export type _ControllerStaticMethod<REQ extends _VovkRequest<undefined, _KnownAny> = _VovkRequest<undefined, Record<string, string>>, PARAMS extends {
61
+ [key: string]: string;
62
+ } = _KnownAny> = ((req: REQ, params: PARAMS) => unknown) & {
63
+ _controller?: _VovkController;
64
+ };
65
+ export type _VovkBody<T extends _ControllerStaticMethod<REQ, PARAMS>, REQ extends _VovkRequest<undefined, _KnownAny> = Parameters<T>[0], PARAMS extends {
66
+ [key: string]: string;
67
+ } = _KnownAny> = Awaited<ReturnType<Parameters<T>[0]['json']>>;
68
+ export type _VovkQuery<T extends _ControllerStaticMethod<REQ, PARAMS>, REQ extends _VovkRequest<undefined, _KnownAny> = Parameters<T>[0], PARAMS extends {
69
+ [key: string]: string;
70
+ } = _KnownAny> = Parameters<T>[0]['nextUrl']['searchParams']['__queryType'];
71
+ export type _VovkParams<T extends _ControllerStaticMethod<REQ, PARAMS>, REQ extends _VovkRequest<undefined, _KnownAny> = Parameters<T>[0], PARAMS extends {
72
+ [key: string]: string;
73
+ } = _KnownAny> = Parameters<T>[1];
74
+ export type _VovkReturnType<T extends _ControllerStaticMethod<REQ, PARAMS>, REQ extends _VovkRequest<undefined, _KnownAny> = Parameters<T>[0], PARAMS extends {
75
+ [key: string]: string;
76
+ } = _KnownAny> = Awaited<ReturnType<T>>;
77
+ export type _StreamAbortMessage = {
78
+ isError: true;
79
+ reason: _KnownAny;
80
+ };
81
+ export declare enum _HttpMethod {
82
+ GET = "GET",
83
+ POST = "POST",
84
+ PUT = "PUT",
85
+ PATCH = "PATCH",
86
+ DELETE = "DELETE",
87
+ HEAD = "HEAD",
88
+ OPTIONS = "OPTIONS"
89
+ }
90
+ export declare enum _HttpStatus {
91
+ NULL = 0,
92
+ CONTINUE = 100,
93
+ SWITCHING_PROTOCOLS = 101,
94
+ PROCESSING = 102,
95
+ EARLYHINTS = 103,
96
+ OK = 200,
97
+ CREATED = 201,
98
+ ACCEPTED = 202,
99
+ NON_AUTHORITATIVE_INFORMATION = 203,
100
+ NO_CONTENT = 204,
101
+ RESET_CONTENT = 205,
102
+ PARTIAL_CONTENT = 206,
103
+ AMBIGUOUS = 300,
104
+ MOVED_PERMANENTLY = 301,
105
+ FOUND = 302,
106
+ SEE_OTHER = 303,
107
+ NOT_MODIFIED = 304,
108
+ TEMPORARY_REDIRECT = 307,
109
+ PERMANENT_REDIRECT = 308,
110
+ BAD_REQUEST = 400,
111
+ UNAUTHORIZED = 401,
112
+ PAYMENT_REQUIRED = 402,
113
+ FORBIDDEN = 403,
114
+ NOT_FOUND = 404,
115
+ METHOD_NOT_ALLOWED = 405,
116
+ NOT_ACCEPTABLE = 406,
117
+ PROXY_AUTHENTICATION_REQUIRED = 407,
118
+ REQUEST_TIMEOUT = 408,
119
+ CONFLICT = 409,
120
+ GONE = 410,
121
+ LENGTH_REQUIRED = 411,
122
+ PRECONDITION_FAILED = 412,
123
+ PAYLOAD_TOO_LARGE = 413,
124
+ URI_TOO_LONG = 414,
125
+ UNSUPPORTED_MEDIA_TYPE = 415,
126
+ REQUESTED_RANGE_NOT_SATISFIABLE = 416,
127
+ EXPECTATION_FAILED = 417,
128
+ I_AM_A_TEAPOT = 418,
129
+ MISDIRECTED = 421,
130
+ UNPROCESSABLE_ENTITY = 422,
131
+ FAILED_DEPENDENCY = 424,
132
+ PRECONDITION_REQUIRED = 428,
133
+ TOO_MANY_REQUESTS = 429,
134
+ INTERNAL_SERVER_ERROR = 500,
135
+ NOT_IMPLEMENTED = 501,
136
+ BAD_GATEWAY = 502,
137
+ SERVICE_UNAVAILABLE = 503,
138
+ GATEWAY_TIMEOUT = 504,
139
+ HTTP_VERSION_NOT_SUPPORTED = 505
140
+ }
package/types.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._HttpStatus = exports._HttpMethod = void 0;
4
+ var _HttpMethod;
5
+ (function (_HttpMethod) {
6
+ _HttpMethod["GET"] = "GET";
7
+ _HttpMethod["POST"] = "POST";
8
+ _HttpMethod["PUT"] = "PUT";
9
+ _HttpMethod["PATCH"] = "PATCH";
10
+ _HttpMethod["DELETE"] = "DELETE";
11
+ _HttpMethod["HEAD"] = "HEAD";
12
+ _HttpMethod["OPTIONS"] = "OPTIONS";
13
+ })(_HttpMethod || (exports._HttpMethod = _HttpMethod = {}));
14
+ var _HttpStatus;
15
+ (function (_HttpStatus) {
16
+ _HttpStatus[_HttpStatus["NULL"] = 0] = "NULL";
17
+ _HttpStatus[_HttpStatus["CONTINUE"] = 100] = "CONTINUE";
18
+ _HttpStatus[_HttpStatus["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
19
+ _HttpStatus[_HttpStatus["PROCESSING"] = 102] = "PROCESSING";
20
+ _HttpStatus[_HttpStatus["EARLYHINTS"] = 103] = "EARLYHINTS";
21
+ _HttpStatus[_HttpStatus["OK"] = 200] = "OK";
22
+ _HttpStatus[_HttpStatus["CREATED"] = 201] = "CREATED";
23
+ _HttpStatus[_HttpStatus["ACCEPTED"] = 202] = "ACCEPTED";
24
+ _HttpStatus[_HttpStatus["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
25
+ _HttpStatus[_HttpStatus["NO_CONTENT"] = 204] = "NO_CONTENT";
26
+ _HttpStatus[_HttpStatus["RESET_CONTENT"] = 205] = "RESET_CONTENT";
27
+ _HttpStatus[_HttpStatus["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
28
+ _HttpStatus[_HttpStatus["AMBIGUOUS"] = 300] = "AMBIGUOUS";
29
+ _HttpStatus[_HttpStatus["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
30
+ _HttpStatus[_HttpStatus["FOUND"] = 302] = "FOUND";
31
+ _HttpStatus[_HttpStatus["SEE_OTHER"] = 303] = "SEE_OTHER";
32
+ _HttpStatus[_HttpStatus["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
33
+ _HttpStatus[_HttpStatus["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
34
+ _HttpStatus[_HttpStatus["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
35
+ _HttpStatus[_HttpStatus["BAD_REQUEST"] = 400] = "BAD_REQUEST";
36
+ _HttpStatus[_HttpStatus["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
37
+ _HttpStatus[_HttpStatus["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
38
+ _HttpStatus[_HttpStatus["FORBIDDEN"] = 403] = "FORBIDDEN";
39
+ _HttpStatus[_HttpStatus["NOT_FOUND"] = 404] = "NOT_FOUND";
40
+ _HttpStatus[_HttpStatus["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
41
+ _HttpStatus[_HttpStatus["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
42
+ _HttpStatus[_HttpStatus["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
43
+ _HttpStatus[_HttpStatus["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
44
+ _HttpStatus[_HttpStatus["CONFLICT"] = 409] = "CONFLICT";
45
+ _HttpStatus[_HttpStatus["GONE"] = 410] = "GONE";
46
+ _HttpStatus[_HttpStatus["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
47
+ _HttpStatus[_HttpStatus["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
48
+ _HttpStatus[_HttpStatus["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
49
+ _HttpStatus[_HttpStatus["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
50
+ _HttpStatus[_HttpStatus["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
51
+ _HttpStatus[_HttpStatus["REQUESTED_RANGE_NOT_SATISFIABLE"] = 416] = "REQUESTED_RANGE_NOT_SATISFIABLE";
52
+ _HttpStatus[_HttpStatus["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
53
+ _HttpStatus[_HttpStatus["I_AM_A_TEAPOT"] = 418] = "I_AM_A_TEAPOT";
54
+ _HttpStatus[_HttpStatus["MISDIRECTED"] = 421] = "MISDIRECTED";
55
+ _HttpStatus[_HttpStatus["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
56
+ _HttpStatus[_HttpStatus["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
57
+ _HttpStatus[_HttpStatus["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
58
+ _HttpStatus[_HttpStatus["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
59
+ _HttpStatus[_HttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
60
+ _HttpStatus[_HttpStatus["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
61
+ _HttpStatus[_HttpStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
62
+ _HttpStatus[_HttpStatus["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
63
+ _HttpStatus[_HttpStatus["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
64
+ _HttpStatus[_HttpStatus["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
65
+ })(_HttpStatus || (exports._HttpStatus = _HttpStatus = {}));
@@ -0,0 +1,3 @@
1
+ import { _worker as worker } from './worker';
2
+ import { _promisifyWorker as promisifyWorker } from './promisifyWorker';
3
+ export { worker, promisifyWorker };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promisifyWorker = exports.worker = void 0;
4
+ const worker_1 = require("./worker");
5
+ Object.defineProperty(exports, "worker", { enumerable: true, get: function () { return worker_1._worker; } });
6
+ const promisifyWorker_1 = require("./promisifyWorker");
7
+ Object.defineProperty(exports, "promisifyWorker", { enumerable: true, get: function () { return promisifyWorker_1._promisifyWorker; } });
@@ -0,0 +1,2 @@
1
+ import type { _WorkerPromiseInstance as WorkerPromiseInstance } from './types';
2
+ export declare function _promisifyWorker<T extends object>(w: Worker, givenWorkerService: object): WorkerPromiseInstance<T>;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._promisifyWorker = void 0;
4
+ function _promisifyWorker(w, givenWorkerService) {
5
+ const workerService = givenWorkerService;
6
+ const instance = {};
7
+ let callsKey = 0;
8
+ if (typeof Worker === 'undefined' || !(w instanceof Worker)) {
9
+ throw new Error('Worker is not provided');
10
+ }
11
+ instance.terminate = () => w.terminate();
12
+ for (const method of Object.keys(workerService._handlers)) {
13
+ const { isGenerator } = workerService._handlers[method];
14
+ const value = workerService[method];
15
+ if (isGenerator) {
16
+ // @ts-expect-error TODO Fix this
17
+ instance[method] = (...args) => {
18
+ const key = callsKey;
19
+ callsKey += 1;
20
+ return {
21
+ async *[Symbol.asyncIterator]() {
22
+ const messageQueue = [];
23
+ let messageResolver = null;
24
+ const onMessage = (e) => {
25
+ const { method: m, key: k } = e.data;
26
+ if (k !== key || m !== method) {
27
+ return;
28
+ }
29
+ if (messageResolver) {
30
+ messageResolver(e.data);
31
+ messageResolver = null;
32
+ }
33
+ else {
34
+ messageQueue.push(e.data);
35
+ }
36
+ };
37
+ const onError = (e) => {
38
+ if (messageResolver) {
39
+ messageResolver({ error: e.error });
40
+ messageResolver = null;
41
+ }
42
+ else {
43
+ messageQueue.push({ error: e.error });
44
+ }
45
+ w.removeEventListener('message', onMessage);
46
+ w.removeEventListener('error', onError);
47
+ throw e.error;
48
+ };
49
+ w.addEventListener('message', onMessage);
50
+ w.addEventListener('error', onError);
51
+ w.postMessage({ key, args, method });
52
+ try {
53
+ while (true) {
54
+ let message = null;
55
+ if (messageQueue.length > 0) {
56
+ message = messageQueue.shift();
57
+ }
58
+ else {
59
+ message = await new Promise((resolve) => {
60
+ messageResolver = resolve;
61
+ });
62
+ }
63
+ const { result, error, done } = message;
64
+ if (error) {
65
+ throw error;
66
+ }
67
+ if (done) {
68
+ break;
69
+ }
70
+ yield result;
71
+ }
72
+ w.removeEventListener('message', onMessage);
73
+ w.removeEventListener('error', onError);
74
+ }
75
+ catch (e) {
76
+ w.removeEventListener('message', onMessage);
77
+ w.removeEventListener('error', onError);
78
+ throw e;
79
+ }
80
+ },
81
+ };
82
+ };
83
+ }
84
+ else {
85
+ // @ts-expect-error TODO Fix this
86
+ instance[method] = (...args) => {
87
+ return new Promise((resolve, reject) => {
88
+ const key = callsKey;
89
+ callsKey += 1;
90
+ const onError = (e) => {
91
+ w.removeEventListener('message', onMessage);
92
+ w.removeEventListener('error', onError);
93
+ reject(e);
94
+ };
95
+ const onMessage = (e) => {
96
+ const { result, error, key: k, method: m } = e.data;
97
+ if (k !== key || m !== method) {
98
+ return;
99
+ }
100
+ w.removeEventListener('message', onMessage);
101
+ w.removeEventListener('error', onError);
102
+ if (error) {
103
+ reject(error);
104
+ }
105
+ else {
106
+ resolve(result);
107
+ }
108
+ };
109
+ w.addEventListener('message', onMessage);
110
+ w.addEventListener('error', onError);
111
+ w.postMessage({ key, args, method });
112
+ });
113
+ };
114
+ }
115
+ }
116
+ return instance;
117
+ }
118
+ exports._promisifyWorker = _promisifyWorker;
@@ -0,0 +1,22 @@
1
+ import type { _KnownAny as KnownAny } from '../types';
2
+ type ToPromise<T> = T extends PromiseLike<unknown> ? T : Promise<T>;
3
+ type ToAsyncGenerator<T> = T extends AsyncGenerator<unknown, unknown, unknown> ? T : T extends Generator<infer U, unknown, unknown> ? AsyncGenerator<U, unknown, unknown> : AsyncGenerator<T, unknown, unknown>;
4
+ type ToProperReturnType<T> = T extends Generator<unknown, unknown, unknown> | AsyncGenerator<unknown, unknown, unknown> ? ToAsyncGenerator<T> : ToPromise<T>;
5
+ export type _WorkerPromiseInstance<T> = {
6
+ [K in keyof T]: T[K] extends (...args: KnownAny[]) => KnownAny ? (...args: Parameters<T[K]>) => ToProperReturnType<ReturnType<T[K]>> : never;
7
+ } & {
8
+ terminate: () => void;
9
+ };
10
+ export interface _WorkerInput {
11
+ method: string;
12
+ args: unknown[];
13
+ key: number;
14
+ }
15
+ export interface _WorkerOutput {
16
+ result?: unknown;
17
+ error?: unknown;
18
+ done?: true;
19
+ key: number;
20
+ method: string;
21
+ }
22
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare function _worker(): (t: object) => void;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._worker = void 0;
4
+ function _worker() {
5
+ return (t) => {
6
+ const target = t;
7
+ target._handlers = {};
8
+ // Experimental: You can pass Worker Service instead of metadata to prommisify worker
9
+ for (const key of Object.getOwnPropertyNames(target)) {
10
+ const member = target[key];
11
+ if (typeof member === 'function') {
12
+ const prototype = Object.getPrototypeOf(member);
13
+ const isGenerator = prototype === Object.getPrototypeOf(function* () { }) ||
14
+ prototype === Object.getPrototypeOf(async function* () { });
15
+ target._handlers[key] = {};
16
+ if (isGenerator) {
17
+ target._handlers[key].isGenerator = true;
18
+ }
19
+ }
20
+ }
21
+ // eslint-disable-next-line no-undef
22
+ if (typeof self === 'undefined')
23
+ return; // no-op in non-worker environment
24
+ // eslint-disable-next-line no-undef
25
+ const w = self;
26
+ w.onmessage = async (evt) => {
27
+ const { method, args, key } = evt.data;
28
+ try {
29
+ const result = await target[method](...args);
30
+ if (result && typeof result === 'object' && 'next' in result && typeof result.next === 'function') {
31
+ const iterable = result;
32
+ for await (const result of iterable) {
33
+ w.postMessage({ result, key, method });
34
+ }
35
+ w.postMessage({ done: true, key, method });
36
+ }
37
+ else {
38
+ w.postMessage({ result, key, method });
39
+ }
40
+ }
41
+ catch (e) {
42
+ w.postMessage({ error: e, key, method });
43
+ }
44
+ };
45
+ };
46
+ }
47
+ exports._worker = _worker;