ranuts 0.1.0-alpha.1 → 0.1.0-alpha.2

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.
Files changed (116) hide show
  1. package/package.json +1 -1
  2. package/dist/src/file/fileInfo.d.ts +0 -7
  3. package/dist/src/file/fs.d.ts +0 -2
  4. package/dist/src/file/readDir.d.ts +0 -6
  5. package/dist/src/file/readFile.d.ts +0 -8
  6. package/dist/src/file/watchFile.d.ts +0 -8
  7. package/dist/src/file/writeFile.d.ts +0 -8
  8. package/dist/src/mode/subscribe.d.ts +0 -16
  9. package/dist/src/ranlog/behavior.d.ts +0 -1
  10. package/dist/src/ranlog/env.d.ts +0 -5
  11. package/dist/src/ranlog/error.d.ts +0 -2
  12. package/dist/src/ranlog/index.d.ts +0 -26
  13. package/dist/src/ranlog/performance.d.ts +0 -21
  14. package/dist/src/ranlog/report.d.ts +0 -7
  15. package/dist/src/ranlog/request.d.ts +0 -18
  16. package/dist/src/ranlog/utils.d.ts +0 -19
  17. package/dist/src/utils/filterObj.d.ts +0 -8
  18. package/dist/src/utils/str2Xml.d.ts +0 -8
  19. package/dist/src/vnode/h.d.ts +0 -6
  20. package/dist/src/vnode/hooks.d.ts +0 -23
  21. package/dist/src/vnode/htmlDomApi.d.ts +0 -33
  22. package/dist/src/vnode/init.d.ts +0 -2
  23. package/dist/src/vnode/is.d.ts +0 -5
  24. package/dist/src/vnode/modules/attributes.d.ts +0 -8
  25. package/dist/src/vnode/modules/class.d.ts +0 -8
  26. package/dist/src/vnode/modules/index.d.ts +0 -7
  27. package/dist/src/vnode/modules/listeners.d.ts +0 -14
  28. package/dist/src/vnode/modules/props.d.ts +0 -8
  29. package/dist/src/vnode/modules/style.d.ts +0 -14
  30. package/dist/src/vnode/vnode.d.ts +0 -31
  31. package/src/astParser/Parser.ts +0 -654
  32. package/src/astParser/Tokenizer.ts +0 -447
  33. package/src/astParser/nodeTypes.ts +0 -194
  34. package/src/astParser/utils.ts +0 -27
  35. package/src/babel/parser.ts +0 -10
  36. package/src/colors/fmt.ts +0 -29
  37. package/src/colors/isColorSupported.ts +0 -13
  38. package/src/file/appendFile.ts +0 -29
  39. package/src/file/fileInfo.ts +0 -22
  40. package/src/file/fs.ts +0 -9
  41. package/src/file/readDir.ts +0 -18
  42. package/src/file/readFile.ts +0 -26
  43. package/src/file/watchFile.ts +0 -31
  44. package/src/file/writeFile.ts +0 -38
  45. package/src/mode/subscribe.ts +0 -89
  46. package/src/ran/commit.ts +0 -0
  47. package/src/ran/dom.ts +0 -0
  48. package/src/ran/hooks.ts +0 -0
  49. package/src/ran/reconcile.ts +0 -0
  50. package/src/ran/schedule.ts +0 -0
  51. package/src/ranlog/behavior.ts +0 -5
  52. package/src/ranlog/console.ts +0 -16
  53. package/src/ranlog/env.ts +0 -29
  54. package/src/ranlog/error.ts +0 -11
  55. package/src/ranlog/performance.ts +0 -65
  56. package/src/ranlog/report.ts +0 -33
  57. package/src/ranlog/request.ts +0 -60
  58. package/src/ranlog/utils.ts +0 -92
  59. package/src/ranpack/ast/Declaration.ts +0 -120
  60. package/src/ranpack/ast/Node.ts +0 -7
  61. package/src/ranpack/ast/Reference.ts +0 -32
  62. package/src/ranpack/ast/Scope.ts +0 -80
  63. package/src/ranpack/bundle.ts +0 -50
  64. package/src/ranpack/graph.ts +0 -143
  65. package/src/ranpack/module.ts +0 -431
  66. package/src/ranpack/moduleLoader.ts +0 -73
  67. package/src/ranpack/plugins.ts +0 -70
  68. package/src/ranpack/statement.ts +0 -66
  69. package/src/ranpack/utils/buildScope.ts +0 -77
  70. package/src/ranpack/utils/findReference.ts +0 -36
  71. package/src/ranpack/utils/isFunctionDeclaration.ts +0 -41
  72. package/src/ranpack/utils/makeLegalIdentifier.ts +0 -18
  73. package/src/ranpack/utils/object.ts +0 -8
  74. package/src/ranpack/utils/resolve.ts +0 -32
  75. package/src/ranpack/utils/walk.ts +0 -66
  76. package/src/ranpack/ws.ts +0 -269
  77. package/src/server/connectType.ts +0 -9
  78. package/src/server/encodeUrl.ts +0 -46
  79. package/src/server/escapeHtml.ts +0 -46
  80. package/src/server/get.ts +0 -36
  81. package/src/server/jitter.ts +0 -77
  82. package/src/server/mimeType.ts +0 -858
  83. package/src/server/paresUrl.ts +0 -40
  84. package/src/server/send.ts +0 -89
  85. package/src/server/server.ts +0 -67
  86. package/src/server/status.ts +0 -191
  87. package/src/server/traverse.ts +0 -54
  88. package/src/server/websocket.ts +0 -200
  89. package/src/sort/bubble.ts +0 -21
  90. package/src/sort/bucket.ts +0 -11
  91. package/src/sort/count.ts +0 -10
  92. package/src/sort/heap.ts +0 -10
  93. package/src/sort/insert.ts +0 -20
  94. package/src/sort/merge.ts +0 -35
  95. package/src/sort/quick.ts +0 -50
  96. package/src/sort/radix.ts +0 -11
  97. package/src/sort/randomArray.ts +0 -21
  98. package/src/sort/select.ts +0 -23
  99. package/src/sort/shell.ts +0 -22
  100. package/src/utils/compose.ts +0 -37
  101. package/src/utils/filterObj.ts +0 -21
  102. package/src/utils/mergeObj.ts +0 -12
  103. package/src/utils/startTask.ts +0 -15
  104. package/src/utils/str2Xml.ts +0 -26
  105. package/src/utils/taskEnd.ts +0 -14
  106. package/src/vnode/h.ts +0 -108
  107. package/src/vnode/hooks.ts +0 -25
  108. package/src/vnode/htmlDomApi.ts +0 -199
  109. package/src/vnode/init.ts +0 -429
  110. package/src/vnode/is.ts +0 -17
  111. package/src/vnode/modules/attributes.ts +0 -70
  112. package/src/vnode/modules/class.ts +0 -46
  113. package/src/vnode/modules/listeners.ts +0 -123
  114. package/src/vnode/modules/props.ts +0 -41
  115. package/src/vnode/modules/style.ts +0 -118
  116. package/src/vnode/vnode.ts +0 -65
@@ -1,40 +0,0 @@
1
- import type { IncomingMessage } from 'node:http'
2
-
3
- interface ParseUrl {
4
- search?: string
5
- query?: string
6
- pathname?: string
7
- path?: string
8
- href?: string
9
- _raw?: string
10
- }
11
- interface Req extends IncomingMessage {
12
- _parsedUrl?: ParseUrl
13
- }
14
- /**
15
- * @description: 解析 IncomingMessage 类型的请求url,返回的类型永远是 ParseUrl
16
- * @param {Req} req
17
- * @return {ParseUrl}
18
- */
19
- export default function (req: Req): ParseUrl | undefined {
20
- const url = req.url
21
- if (url === void 0) return
22
-
23
- let obj = req._parsedUrl
24
- if (obj && obj._raw === url) return obj
25
-
26
- obj = {}
27
- obj.query = obj.search = undefined
28
- obj.href = obj.path = obj.pathname = url
29
-
30
- const idx = url.indexOf('?', 1)
31
- if (idx !== -1) {
32
- obj.search = url.substring(idx)
33
- obj.query = obj.search.substring(1)
34
- obj.pathname = url.substring(0, idx)
35
- }
36
-
37
- obj._raw = url
38
-
39
- return (req._parsedUrl = obj)
40
- }
@@ -1,89 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import type { IncomingMessage, ServerResponse } from 'node:http'
4
- import type { MiddlewareFunction, Next } from '@/server/server'
5
- import { queryMime, setMime } from '@/node/http/mimeType'
6
-
7
- interface Option {
8
- pathname: string
9
- fileTypes: Record<string, string>
10
- }
11
- const staticMiddleware = (option: Partial<Option> = {}): MiddlewareFunction => {
12
- const { pathname, fileTypes = {} } = option
13
- return async (
14
- req: IncomingMessage,
15
- res: ServerResponse,
16
- next: Next,
17
- ): Promise<void> => {
18
- try {
19
- if (req.url) {
20
- const htmlContentType = 'text/html'
21
- // 获取传入的地址,如果没有,取当前的目录
22
- const dirPath = pathname ? pathname : process.cwd()
23
- // 静态资源文件根路径
24
- const root = path.normalize(path.resolve(dirPath))
25
- // 获取访问的文件类型
26
- const extension = path.extname(req.url).slice(1)
27
- // 增加mimeType
28
- Object.keys(fileTypes).forEach((key) =>
29
- setMime(key, fileTypes[key]),
30
- )
31
- // 文件类型后缀
32
- const type = extension ? queryMime(extension) : htmlContentType
33
- // 是否支持的文件类型
34
- const supportedExtension = Boolean(type)
35
- // 如果这个文件类型不允许访问,则直接返回404
36
- if (!supportedExtension) {
37
- res.writeHead(404, { 'Content-Type': 'text/html' })
38
- res.end('404: File not found')
39
- return
40
- }
41
-
42
- // 通过url获取访问的文件名称
43
- let fileName = req.url
44
- // 如果访问的路径是 /
45
- if (req.url === '/') {
46
- // 则文件名是 index.html
47
- fileName = 'index.html'
48
- // 如果访问的文件类型不在允许的类型里面,默认返回index.html
49
- } else if (!extension) {
50
- try {
51
- // 检测文件是否允许访问
52
- fs.accessSync(path.join(root, req.url + '.html'), fs.constants.F_OK)
53
- // 当允许访问时,则返回对应的页面
54
- fileName = req.url + '.html'
55
- } catch (e) {
56
- // 否则直接返回 index.html
57
- fileName = path.join(req.url, 'index.html')
58
- }
59
- }
60
- // 有文件名且访问的文件类型也允许访问
61
- const filePath = path.join(root, fileName)
62
- const isPathUnderRoot = path
63
- .normalize(path.resolve(filePath))
64
- .startsWith(root)
65
-
66
- if (!isPathUnderRoot) {
67
- res.writeHead(404, { 'Content-Type': 'text/html' })
68
- res.end('404: File not found')
69
- return
70
- }
71
-
72
- fs.readFile(filePath, (err, data) => {
73
- if (err) {
74
- res.writeHead(404, { 'Content-Type': 'text/html' })
75
- res.end('404: File not found')
76
- } else {
77
- res.writeHead(200, { 'Content-Type': type })
78
- res.end(data)
79
- }
80
- })
81
- } else {
82
- console.log('request has not url')
83
- }
84
- await next()
85
- } catch (error) {}
86
- }
87
- }
88
-
89
- export default staticMiddleware
@@ -1,67 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from 'node:http'
2
- import http from 'node:http'
3
-
4
- export type Next = () => Promise<never> | Promise<void>
5
-
6
- export type MiddlewareFunction = (
7
- req: IncomingMessage,
8
- res: ServerResponse,
9
- next: Next,
10
- ) => void | Promise<void>
11
-
12
- class Server {
13
- stack: Array<MiddlewareFunction>
14
- constructor() {
15
- this.stack = []
16
- /**
17
- * @description: 添加中间件
18
- */
19
- }
20
- use(handle: MiddlewareFunction): void {
21
- if (!handle) {
22
- throw new Error('the use function has an incorrect argument')
23
- }
24
- this.stack.push(handle)
25
- }
26
- listen(
27
- ...args: any
28
- ): http.Server<typeof IncomingMessage, typeof ServerResponse> {
29
- const fn = compose(this.stack)
30
- const server = http.createServer((req, res) => {
31
- fn(req, res).then().catch(onerror)
32
- })
33
- return server.listen(...args)
34
- }
35
- }
36
-
37
- function onerror(err: Error) {
38
- console.error(err.stack || err.toString())
39
- }
40
-
41
- function compose(middleware: Array<MiddlewareFunction>) {
42
- if (!Array.isArray(middleware))
43
- throw new TypeError('Middleware stack must be an array!')
44
- for (const fn of middleware) {
45
- if (typeof fn !== 'function')
46
- throw new TypeError('Middleware must be composed of functions!')
47
- }
48
- return function (req: IncomingMessage, res: ServerResponse, next?: Next) {
49
- let index = -1
50
- function dispatch(i: number): Promise<never> | Promise<void> {
51
- if (i <= index)
52
- return Promise.reject(new Error('next() called multiple times'))
53
- index = i
54
- let fn = middleware[i]
55
- if (i === middleware.length && next) fn = next
56
- if (!fn) return Promise.resolve()
57
- try {
58
- return Promise.resolve(fn(req, res, dispatch.bind(null, i + 1)))
59
- } catch (err) {
60
- return Promise.reject(err)
61
- }
62
- }
63
- return dispatch(0)
64
- }
65
- }
66
-
67
- export default Server
@@ -1,191 +0,0 @@
1
- // code map message
2
- const codes = new Map([
3
- [100, 'Continue'],
4
- [101, 'Switching Protocols'],
5
- [102, 'Processing'],
6
- [103, 'Early Hints'],
7
- [200, 'OK'],
8
- [201, 'Created'],
9
- [202, 'Accepted'],
10
- [203, 'Non-Authoritative Information'],
11
- [204, 'No Content'],
12
- [205, 'Reset Content'],
13
- [206, 'Partial Content'],
14
- [207, 'Multi-Status'],
15
- [208, 'Already Reported'],
16
- [226, 'IM Used'],
17
- [300, 'Multiple Choices'],
18
- [301, 'Moved Permanently'],
19
- [302, 'Found'],
20
- [303, 'See Other'],
21
- [304, 'Not Modified'],
22
- [305, 'Use Proxy'],
23
- [307, 'Temporary Redirect'],
24
- [308, 'Permanent Redirect'],
25
- [400, 'Bad Request'],
26
- [401, 'Unauthorized'],
27
- [402, 'Payment Required'],
28
- [403, 'Forbidden'],
29
- [404, 'Not Found'],
30
- [405, 'Method Not Allowed'],
31
- [406, 'Not Acceptable'],
32
- [407, 'Proxy Authentication Required'],
33
- [408, 'Request Timeout'],
34
- [409, 'Conflict'],
35
- [410, 'Gone'],
36
- [411, 'Length Required'],
37
- [412, 'Precondition Failed'],
38
- [413, 'Payload Too Large'],
39
- [414, 'URI Too Long'],
40
- [415, 'Unsupported Media Type'],
41
- [416, 'Range Not Satisfiable'],
42
- [417, 'Expectation Failed'],
43
- [418, "I'm a Teapot"],
44
- [421, 'Misdirected Request'],
45
- [422, 'Unprocessable Entity'],
46
- [423, 'Locked'],
47
- [424, 'Failed Dependency'],
48
- [425, 'Too Early'],
49
- [426, 'Upgrade Required'],
50
- [428, 'Precondition Required'],
51
- [429, 'Too Many Requests'],
52
- [431, 'Request Header Fields Too Large'],
53
- [451, 'Unavailable For Legal Reasons'],
54
- [500, 'Internal Server Error'],
55
- [501, 'Not Implemented'],
56
- [502, 'Bad Gateway'],
57
- [503, 'Service Unavailable'],
58
- [504, 'Gateway Timeout'],
59
- [505, 'HTTP Version Not Supported'],
60
- [506, 'Variant Also Negotiates'],
61
- [507, 'Insufficient Storage'],
62
- [508, 'Loop Detected'],
63
- [509, 'Bandwidth Limit Exceeded'],
64
- [510, 'Not Extended'],
65
- [511, 'Network Authentication Required'],
66
- ])
67
-
68
- const status = {
69
- // status code to message map
70
- message: codes,
71
- // status message (lower-case) to code map
72
- code: createMessageToStatusCodeMap(codes),
73
- // array of status codes
74
- codes: createStatusCodeList(codes),
75
- // status codes for redirects
76
- redirect: {
77
- 300: true,
78
- 301: true,
79
- 302: true,
80
- 303: true,
81
- 305: true,
82
- 307: true,
83
- 308: true,
84
- },
85
- // status codes for empty bodies
86
- empty: {
87
- 204: true,
88
- 205: true,
89
- 304: true,
90
- },
91
- // status codes for when you should retry the request
92
- retry: {
93
- 502: true,
94
- 503: true,
95
- 504: true,
96
- },
97
- }
98
-
99
- /**
100
- * @private
101
- * @description: Create a map of message to status code.
102
- * @param {Record} codes
103
- * @param {*} string
104
- * @return {Record<string, number>}
105
- */
106
- function createMessageToStatusCodeMap(codes: Map<number, string>) {
107
- const map: Map<string, number> = new Map()
108
- for (const [status, message] of codes) {
109
- map.set(message.toLowerCase(), status)
110
- }
111
- return map
112
- }
113
-
114
- /**
115
- * Create a list of all status codes.
116
- * @private
117
- */
118
-
119
- function createStatusCodeList(codes: Map<number, string>) {
120
- const codeList: Array<number> = []
121
- for (const [status, _] of codes) {
122
- codeList.push(status)
123
- }
124
- return codeList
125
- }
126
-
127
- /**
128
- * Get the status code for given message.
129
- * @private
130
- */
131
-
132
- function getStatusCode(message: string) {
133
- const msg = message.toLowerCase()
134
- status.code.has(msg)
135
- if (!status.code.has(msg)) {
136
- throw new Error('invalid status message: "' + message + '"')
137
- }
138
-
139
- return status.code.get(msg)
140
- }
141
-
142
- /**
143
- * Get the status message for given code.
144
- * @private
145
- */
146
-
147
- function getStatusMessage(code: number) {
148
- if (!status.message.has(code)) {
149
- throw new Error('invalid status code: ' + code)
150
- }
151
-
152
- return status.message.get(code)
153
- }
154
-
155
- /**
156
- * Get the status code.
157
- *
158
- * Given a number, this will throw if it is not a known status
159
- * code, otherwise the code will be returned. Given a string,
160
- * the string will be parsed for a number and return the code
161
- * if valid, otherwise will lookup the code assuming this is
162
- * the status message.
163
- *
164
- * @param {string|number} code
165
- * @returns {number}
166
- * @public
167
- */
168
-
169
- function getStatus(code?: number | string): number | string | undefined {
170
- if (typeof code === 'number') {
171
- // return message
172
- return getStatusMessage(code)
173
- }
174
-
175
- if (typeof code !== 'string') {
176
- throw new TypeError('code must be a number or string')
177
- }
178
-
179
- // '403'
180
- const n = parseInt(code, 10)
181
- if (!isNaN(n) && status.codes.includes(n)) {
182
- // return message
183
- return getStatusMessage(n)
184
- }
185
- // return code
186
- return getStatusCode(code)
187
- }
188
-
189
- export default status
190
-
191
- export { getStatus }
@@ -1,54 +0,0 @@
1
- import { join, resolve } from 'node:path'
2
- import type { Stats } from 'node:fs'
3
- import { readdir, readdirSync, stat, statSync } from 'node:fs'
4
- import { promisify } from 'node:util'
5
-
6
- const toStats = promisify(stat)
7
- const toRead = promisify(readdir)
8
-
9
- type Caller = (relPath: string, absPath: string, stats: Stats) => any
10
- /**
11
- * @description: 递归遍历每一个目录,为找到的文件都执行一个函数
12
- * @param {string} dir
13
- * @param {Caller} callback
14
- * @param {*} pre
15
- */
16
- export async function traverse(
17
- dir: string,
18
- callback: Caller,
19
- pre = '',
20
- ): Promise<any> {
21
- dir = resolve('.', dir)
22
- await toRead(dir).then((arr) => {
23
- return Promise.all(
24
- arr.map((str) => {
25
- const abs = join(dir, str)
26
- return toStats(abs).then((stats) => {
27
- return stats.isDirectory()
28
- ? traverse(abs, callback, join(pre, str))
29
- : callback(join(pre, str), abs, stats)
30
- })
31
- }),
32
- )
33
- })
34
- }
35
- /**
36
- * @description: 同步方法,递归遍历每一个目录,为找到的文件都执行一个函数
37
- * @param {string} dir
38
- * @param {Caller} callback
39
- * @param {*} pre
40
- */
41
- export function traverseSync(dir: string, callback: Caller, pre = ''): void {
42
- dir = resolve('.', dir)
43
- const arr = readdirSync(dir)
44
- let i = 0,
45
- abs,
46
- stats
47
- for (; i < arr.length; i++) {
48
- abs = join(dir, arr[i])
49
- stats = statSync(abs)
50
- stats.isDirectory()
51
- ? traverseSync(abs, callback, join(pre, arr[i]))
52
- : callback(join(pre, arr[i]), abs, stats)
53
- }
54
- }
@@ -1,200 +0,0 @@
1
- import http from 'node:http'
2
- import crypto from 'node:crypto'
3
- import type internal from 'node:stream'
4
- import EventEmitter from '@/designMode/EventEmitter'
5
-
6
- interface FrameMeta {
7
- fin: boolean;
8
- opcode: number;
9
- mask: boolean;
10
- maskKey: Buffer | null;
11
- payloadSize: number;
12
- size: number;
13
- metaSize: number;
14
- }
15
-
16
- const sixteenBitsMax = 65535 // 65536 is the max of 16 bits
17
-
18
- const opcodeMap = {
19
- text: 129 // 129 = 10000001, opcode = 0x1
20
- }
21
-
22
- export class Client extends EventEmitter {
23
- socket: internal.Duplex
24
- connectTime: number;
25
- constructor(socket: internal.Duplex) {
26
- super()
27
- this.socket = socket
28
- this.connectTime = Date.now()
29
- }
30
- createFrame(content: string, options?: { opcode: number; }):Buffer {
31
- const size = Buffer.byteLength(content);
32
- let buf
33
- if (size > sixteenBitsMax) {
34
- buf = Buffer.alloc(10 + size);
35
- buf[1] = 127;
36
- buf.writeUInt32BE(size, 6);
37
- buf.write(content, 10);
38
- } else if (size > 125) {
39
- buf = Buffer.alloc(4 + size);
40
- buf[1] = 126;
41
- buf.writeUInt16BE(size, 2);
42
- buf.write(content, 4);
43
- } else {
44
- buf = Buffer.alloc(2 + size);
45
- buf[1] = size;
46
- buf.write(content, 2);
47
- }
48
- if (options) {
49
- const { opcode } = options;
50
- if (opcode && opcode < 15 && opcode >= 0) buf[0] = 128 | opcode;
51
- }
52
- else buf[0] = opcodeMap.text
53
- return buf;
54
- }
55
- send(data: string, options?: { opcode: number; }):void {
56
- this.socket.write(this.createFrame(data, options));
57
- }
58
- ping():void {
59
- this.socket.write(this.createFrame("", { opcode: 9 }));
60
- }
61
- pong():void {
62
- this.socket.write(this.createFrame("", { opcode: 10 }));
63
- }
64
- close():void {
65
- this.socket.write(this.createFrame("", { opcode: 8 }));
66
- this.socket.destroy();
67
- this.emit("close");
68
- }
69
- }
70
-
71
- class WebSocket extends EventEmitter {
72
- server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
73
- clients: Array<Client>
74
- constructor({ port = 30104 }: { port: number }) {
75
- super()
76
- this.server = http.createServer();
77
- this.server.listen(port);
78
- this.clients = []
79
- this.server.on("upgrade", (req, socket) => this.create(req, socket))
80
- }
81
- /**
82
- * @description: 向所有 client 广播
83
- * @param {string} data
84
- */
85
- broadcast(data: string): void {
86
- this.clients.forEach((client) => client.send(data));
87
- }
88
- /**
89
- * @description: 创建client
90
- * @param {http} req
91
- * @param {internal} socket
92
- */
93
- create(req: http.IncomingMessage, socket: internal.Duplex): void {
94
- socket.write([
95
- "HTTP/1.1 101 Switching Protocols",
96
- "Upgrade: websocket",
97
- "Connection: Upgrade",
98
- "Sec-WebSocket-Accept: " + crypto.createHash("sha1").update(req.headers['sec-websocket-key'] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")
99
- ].join("\n") + "\n\n");
100
- const client = new Client(socket)
101
- this.addListenCloseClient(client)
102
- this.clients.push(client);
103
- this.emit("connect", client);
104
-
105
- let buf = Buffer.allocUnsafe(0);
106
- let data = Buffer.allocUnsafe(0);
107
- /**
108
- * @description: 处理帧meta
109
- * @param {FrameMeta} meta
110
- */
111
- const handleFrameMeta = (meta: FrameMeta) => {
112
- const metaLength = meta.metaSize
113
- buf.subarray(0, metaLength)
114
- buf = buf.subarray(metaLength);
115
- return buf
116
- }
117
- /**
118
- * @description: 处理帧内容
119
- * @param {FrameMeta} meta
120
- */
121
- const handleFrameContent = (meta: FrameMeta) => {
122
- const size = meta.size
123
- const buffer = buf.subarray(0, size)
124
- data = Buffer.concat([data, this.iMask(buffer, meta.maskKey)]);
125
- if (meta.fin) {
126
- if (meta.opcode === 8) return client.close();
127
- if (meta.opcode === 9) return client.pong();
128
- client.emit("data", data);
129
- data = Buffer.allocUnsafe(0);
130
- }
131
- buf = buf.subarray(size);
132
- }
133
- socket.on("data", (chunk) => {
134
- buf = Buffer.concat([buf, chunk]);
135
- const meta = this.parseFrameMeta(buf);
136
- handleFrameMeta(meta)
137
- handleFrameContent(meta)
138
- });
139
-
140
- socket.on("end", () => {
141
- client.close();
142
- });
143
-
144
- socket.on("error", (err) => {
145
- client.emit("error", err);
146
- client.close();
147
- });
148
- }
149
- /**
150
- * @description: 增加 client 监听关闭事件
151
- * @param {Client} client
152
- */
153
- addListenCloseClient(client: Client): void {
154
- client.on('close', () => {
155
- const index = this.clients.indexOf(client);
156
- if (index === -1) return false;
157
- this.clients.splice(index, 1);
158
- })
159
- }
160
- /**
161
- * @description: 解析帧meta
162
- * @param {Buffer} source
163
- * @return {FrameMeta}
164
- */
165
- parseFrameMeta(source: Buffer): FrameMeta {
166
- const src = Buffer.from(source);
167
- const payloadSize = src[1] & 127;
168
- let size = 0;
169
- let metaSize = 0;
170
- const masked = src[1] >= 128;
171
- if (payloadSize === 127) {
172
- size = src.readUInt32BE(6);
173
- metaSize = 10;
174
- } else if (payloadSize === 126) {
175
- size = src.readUInt16BE(2);
176
- metaSize = 4;
177
- } else {
178
- size = payloadSize;
179
- metaSize = 2;
180
- }
181
- return {
182
- fin: src[0] >= 128,
183
- opcode: src[0] & 15,
184
- mask: masked,
185
- maskKey: masked ? src.subarray(metaSize, metaSize + (masked ? 4 : 0)) : null,
186
- payloadSize,
187
- size,
188
- metaSize: metaSize + (masked ? 4 : 0)
189
- };
190
- }
191
- iMask(data: Buffer, key: Buffer | null): Buffer {
192
- if (!key) return data;
193
- const buffer = Buffer.from(data);
194
- for (let i = 0; i < buffer.length; ++i) buffer[i] = buffer[i] ^ key[i % 4];
195
- return buffer;
196
- }
197
- }
198
-
199
-
200
- export default WebSocket
@@ -1,21 +0,0 @@
1
- /**
2
- * @description: 冒泡排序,两两比较,交换位置,遍历n^2
3
- * @param {Array} list
4
- * @return {Array}
5
- */
6
- const bubble = (list: Array<number>): Array<number> => {
7
- const length = list.length
8
- for (let i = 0; i < length; i++) {
9
- for (let j = 0; j < length; j++) {
10
- let temp
11
- if (list[j] > list[i]) {
12
- temp = list[j]
13
- list[j] = list[i]
14
- list[i] = temp
15
- }
16
- }
17
- }
18
- return list
19
- }
20
-
21
- export default bubble
@@ -1,11 +0,0 @@
1
- /**
2
- * @description: 桶排序
3
- * @param {Array<number>} list
4
- * @return {Array<number>}
5
- */
6
- const bucket = (list: Array<number>): Array<number> => {
7
- return list
8
- }
9
-
10
- export default bucket
11
-
package/src/sort/count.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @description: 计数排序
3
- * @param {Array<number>} list
4
- * @return {Array<number>}
5
- */
6
- const count = (list: Array<number>): Array<number> => {
7
- return list
8
- }
9
-
10
- export default count
package/src/sort/heap.ts DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @description: 堆排序
3
- * @param {Array} list
4
- * @return {Array}
5
- */
6
- const heap = (list: Array<string>): Array<string> => {
7
- return list
8
- }
9
-
10
- export default heap