@aiszlab/relax 1.5.4 → 1.5.6

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.
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var _regeneratorRuntime = require('@babel/runtime/helpers/regeneratorRuntime');
4
+ var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
5
+
6
+ var clipboard = /*#__PURE__*/function () {
7
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(value) {
8
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
9
+ while (1) switch (_context.prev = _context.next) {
10
+ case 0:
11
+ _context.next = 2;
12
+ return navigator.clipboard.writeText(value);
13
+ case 2:
14
+ return _context.abrupt("return", _context.sent);
15
+ case 3:
16
+ case "end":
17
+ return _context.stop();
18
+ }
19
+ }, _callee);
20
+ }));
21
+ return function clipboard(_x) {
22
+ return _ref.apply(this, arguments);
23
+ };
24
+ }();
25
+
26
+ exports.clipboard = clipboard;
@@ -0,0 +1,24 @@
1
+ import _regeneratorRuntime from '@babel/runtime/helpers/regeneratorRuntime';
2
+ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
3
+
4
+ var clipboard = /*#__PURE__*/function () {
5
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(value) {
6
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
7
+ while (1) switch (_context.prev = _context.next) {
8
+ case 0:
9
+ _context.next = 2;
10
+ return navigator.clipboard.writeText(value);
11
+ case 2:
12
+ return _context.abrupt("return", _context.sent);
13
+ case 3:
14
+ case "end":
15
+ return _context.stop();
16
+ }
17
+ }, _callee);
18
+ }));
19
+ return function clipboard(_x) {
20
+ return _ref.apply(this, arguments);
21
+ };
22
+ }();
23
+
24
+ export { clipboard };
@@ -2,8 +2,10 @@
2
2
 
3
3
  var scrollTo = require('./scroll-to.cjs');
4
4
  var contains = require('./contains.cjs');
5
+ var clipboard = require('./clipboard.cjs');
5
6
 
6
7
 
7
8
 
8
9
  exports.scrollTo = scrollTo.scrollTo;
9
10
  exports.contains = contains.contains;
11
+ exports.clipboard = clipboard.clipboard;
@@ -1,4 +1,6 @@
1
1
  import { scrollTo, type Orientation } from "./scroll-to";
2
2
  import { contains, type Containable } from "./contains";
3
+ import { clipboard } from "./clipboard";
4
+ export { clipboard };
3
5
  export { scrollTo, contains };
4
6
  export type { Containable, Orientation };
@@ -1,2 +1,3 @@
1
1
  export { scrollTo } from './scroll-to.mjs';
2
2
  export { contains } from './contains.mjs';
3
+ export { clipboard } from './clipboard.mjs';
@@ -0,0 +1,142 @@
1
+ 'use strict';
2
+
3
+ var _regeneratorRuntime = require('@babel/runtime/helpers/regeneratorRuntime');
4
+ var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
5
+ var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
6
+ var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
7
+ var parse = require('./parse.cjs');
8
+
9
+ var _excluded = ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden"];
10
+ var EventStreamContentType = "text/event-stream";
11
+ var DefaultRetryInterval = 1000;
12
+ var LastEventId = "last-event-id";
13
+ function fetchEventSource(input, _ref) {
14
+ var inputSignal = _ref.signal,
15
+ inputHeaders = _ref.headers,
16
+ inputOnOpen = _ref.onopen,
17
+ onmessage = _ref.onmessage,
18
+ onclose = _ref.onclose,
19
+ onerror = _ref.onerror,
20
+ openWhenHidden = _ref.openWhenHidden,
21
+ rest = _objectWithoutProperties(_ref, _excluded);
22
+ return new Promise(function (resolve, reject) {
23
+ // make a copy of the input headers since we may modify it below:
24
+ var headers = _objectSpread({}, inputHeaders);
25
+ if (!headers.accept) {
26
+ headers.accept = EventStreamContentType;
27
+ }
28
+ var curRequestController;
29
+ function onVisibilityChange() {
30
+ curRequestController.abort(); // close existing request on every visibility change
31
+ if (!document.hidden) {
32
+ create(); // page is now visible again, recreate request.
33
+ }
34
+ }
35
+ if (!openWhenHidden) {
36
+ document.addEventListener("visibilitychange", onVisibilityChange);
37
+ }
38
+ var retryInterval = DefaultRetryInterval;
39
+ var retryTimer = 0;
40
+ function dispose() {
41
+ document.removeEventListener("visibilitychange", onVisibilityChange);
42
+ window.clearTimeout(retryTimer);
43
+ curRequestController.abort();
44
+ }
45
+ // if the incoming signal aborts, dispose resources and resolve:
46
+ inputSignal === null || inputSignal === void 0 || inputSignal.addEventListener("abort", function () {
47
+ dispose();
48
+ resolve(); // don't waste time constructing/logging errors
49
+ });
50
+ var onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen;
51
+ function create() {
52
+ return _create.apply(this, arguments);
53
+ }
54
+ function _create() {
55
+ _create = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
56
+ var response, _onerror, interval;
57
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
58
+ while (1) switch (_context.prev = _context.next) {
59
+ case 0:
60
+ curRequestController = new AbortController();
61
+ _context.prev = 1;
62
+ _context.next = 4;
63
+ return fetch(input, _objectSpread(_objectSpread({}, rest), {}, {
64
+ headers: headers,
65
+ signal: curRequestController.signal
66
+ }));
67
+ case 4:
68
+ response = _context.sent;
69
+ _context.next = 7;
70
+ return onopen(response);
71
+ case 7:
72
+ _context.next = 9;
73
+ return parse.getBytes(response.body, parse.getLines(parse.getMessages(function (id) {
74
+ if (id) {
75
+ // store the id and send it back on the next retry:
76
+ headers[LastEventId] = id;
77
+ } else {
78
+ // don't send the last-event-id header anymore:
79
+ delete headers[LastEventId];
80
+ }
81
+ }, function (retry) {
82
+ retryInterval = retry;
83
+ }, onmessage)));
84
+ case 9:
85
+ onclose === null || onclose === void 0 || onclose();
86
+ dispose();
87
+ resolve();
88
+ _context.next = 17;
89
+ break;
90
+ case 14:
91
+ _context.prev = 14;
92
+ _context.t0 = _context["catch"](1);
93
+ if (!curRequestController.signal.aborted) {
94
+ // if we haven't aborted the request ourselves:
95
+ try {
96
+ // check if we need to retry:
97
+ interval = (_onerror = onerror === null || onerror === void 0 ? void 0 : onerror(_context.t0)) !== null && _onerror !== void 0 ? _onerror : retryInterval;
98
+ window.clearTimeout(retryTimer);
99
+ retryTimer = window.setTimeout(create, interval);
100
+ } catch (innerErr) {
101
+ // we should not retry anymore:
102
+ dispose();
103
+ reject(innerErr);
104
+ }
105
+ }
106
+ case 17:
107
+ case "end":
108
+ return _context.stop();
109
+ }
110
+ }, _callee, null, [[1, 14]]);
111
+ }));
112
+ return _create.apply(this, arguments);
113
+ }
114
+ create();
115
+ });
116
+ }
117
+ function defaultOnOpen(_x) {
118
+ return _defaultOnOpen.apply(this, arguments);
119
+ }
120
+ function _defaultOnOpen() {
121
+ _defaultOnOpen = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(response) {
122
+ var contentType;
123
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
124
+ while (1) switch (_context2.prev = _context2.next) {
125
+ case 0:
126
+ contentType = response.headers.get("content-type");
127
+ if (contentType !== null && contentType !== void 0 && contentType.startsWith(EventStreamContentType)) {
128
+ _context2.next = 3;
129
+ break;
130
+ }
131
+ throw new Error("Expected content-type to be ".concat(EventStreamContentType, ", Actual: ").concat(contentType));
132
+ case 3:
133
+ case "end":
134
+ return _context2.stop();
135
+ }
136
+ }, _callee2);
137
+ }));
138
+ return _defaultOnOpen.apply(this, arguments);
139
+ }
140
+
141
+ exports.EventStreamContentType = EventStreamContentType;
142
+ exports.fetchEventSource = fetchEventSource;
@@ -0,0 +1,42 @@
1
+ import { EventSourceMessage } from "./parse";
2
+ export declare const EventStreamContentType = "text/event-stream";
3
+ export interface FetchEventSourceInit extends RequestInit {
4
+ /**
5
+ * The request headers. FetchEventSource only supports the Record<string,string> format.
6
+ */
7
+ headers?: Record<string, string>;
8
+ /**
9
+ * Called when a response is received. Use this to validate that the response
10
+ * actually matches what you expect (and throw if it doesn't.) If not provided,
11
+ * will default to a basic validation to ensure the content-type is text/event-stream.
12
+ */
13
+ onopen?: (response: Response) => Promise<void>;
14
+ /**
15
+ * Called when a message is received. NOTE: Unlike the default browser
16
+ * EventSource.onmessage, this callback is called for _all_ events,
17
+ * even ones with a custom `event` field.
18
+ */
19
+ onmessage?: (ev: EventSourceMessage) => void;
20
+ /**
21
+ * Called when a response finishes. If you don't expect the server to kill
22
+ * the connection, you can throw an exception here and retry using onerror.
23
+ */
24
+ onclose?: () => void;
25
+ /**
26
+ * Called when there is any error making the request / processing messages /
27
+ * handling callbacks etc. Use this to control the retry strategy: if the
28
+ * error is fatal, rethrow the error inside the callback to stop the entire
29
+ * operation. Otherwise, you can return an interval (in milliseconds) after
30
+ * which the request will automatically retry (with the last-event-id).
31
+ * If this callback is not specified, or it returns undefined, fetchEventSource
32
+ * will treat every error as retriable and will try again after 1 second.
33
+ */
34
+ onerror?: (err: any) => number | null | undefined | void;
35
+ /**
36
+ * If true, will keep the request open even if the document is hidden.
37
+ * By default, fetchEventSource will close the request and reopen it
38
+ * automatically when the document becomes visible again.
39
+ */
40
+ openWhenHidden?: boolean;
41
+ }
42
+ export declare function fetchEventSource(input: RequestInfo, { signal: inputSignal, headers: inputHeaders, onopen: inputOnOpen, onmessage, onclose, onerror, openWhenHidden, ...rest }: FetchEventSourceInit): Promise<void>;
@@ -0,0 +1,139 @@
1
+ import _regeneratorRuntime from '@babel/runtime/helpers/regeneratorRuntime';
2
+ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
3
+ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
4
+ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
5
+ import { getBytes, getLines, getMessages } from './parse.mjs';
6
+
7
+ var _excluded = ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden"];
8
+ var EventStreamContentType = "text/event-stream";
9
+ var DefaultRetryInterval = 1000;
10
+ var LastEventId = "last-event-id";
11
+ function fetchEventSource(input, _ref) {
12
+ var inputSignal = _ref.signal,
13
+ inputHeaders = _ref.headers,
14
+ inputOnOpen = _ref.onopen,
15
+ onmessage = _ref.onmessage,
16
+ onclose = _ref.onclose,
17
+ onerror = _ref.onerror,
18
+ openWhenHidden = _ref.openWhenHidden,
19
+ rest = _objectWithoutProperties(_ref, _excluded);
20
+ return new Promise(function (resolve, reject) {
21
+ // make a copy of the input headers since we may modify it below:
22
+ var headers = _objectSpread({}, inputHeaders);
23
+ if (!headers.accept) {
24
+ headers.accept = EventStreamContentType;
25
+ }
26
+ var curRequestController;
27
+ function onVisibilityChange() {
28
+ curRequestController.abort(); // close existing request on every visibility change
29
+ if (!document.hidden) {
30
+ create(); // page is now visible again, recreate request.
31
+ }
32
+ }
33
+ if (!openWhenHidden) {
34
+ document.addEventListener("visibilitychange", onVisibilityChange);
35
+ }
36
+ var retryInterval = DefaultRetryInterval;
37
+ var retryTimer = 0;
38
+ function dispose() {
39
+ document.removeEventListener("visibilitychange", onVisibilityChange);
40
+ window.clearTimeout(retryTimer);
41
+ curRequestController.abort();
42
+ }
43
+ // if the incoming signal aborts, dispose resources and resolve:
44
+ inputSignal === null || inputSignal === void 0 || inputSignal.addEventListener("abort", function () {
45
+ dispose();
46
+ resolve(); // don't waste time constructing/logging errors
47
+ });
48
+ var onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen;
49
+ function create() {
50
+ return _create.apply(this, arguments);
51
+ }
52
+ function _create() {
53
+ _create = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
54
+ var response, _onerror, interval;
55
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
56
+ while (1) switch (_context.prev = _context.next) {
57
+ case 0:
58
+ curRequestController = new AbortController();
59
+ _context.prev = 1;
60
+ _context.next = 4;
61
+ return fetch(input, _objectSpread(_objectSpread({}, rest), {}, {
62
+ headers: headers,
63
+ signal: curRequestController.signal
64
+ }));
65
+ case 4:
66
+ response = _context.sent;
67
+ _context.next = 7;
68
+ return onopen(response);
69
+ case 7:
70
+ _context.next = 9;
71
+ return getBytes(response.body, getLines(getMessages(function (id) {
72
+ if (id) {
73
+ // store the id and send it back on the next retry:
74
+ headers[LastEventId] = id;
75
+ } else {
76
+ // don't send the last-event-id header anymore:
77
+ delete headers[LastEventId];
78
+ }
79
+ }, function (retry) {
80
+ retryInterval = retry;
81
+ }, onmessage)));
82
+ case 9:
83
+ onclose === null || onclose === void 0 || onclose();
84
+ dispose();
85
+ resolve();
86
+ _context.next = 17;
87
+ break;
88
+ case 14:
89
+ _context.prev = 14;
90
+ _context.t0 = _context["catch"](1);
91
+ if (!curRequestController.signal.aborted) {
92
+ // if we haven't aborted the request ourselves:
93
+ try {
94
+ // check if we need to retry:
95
+ interval = (_onerror = onerror === null || onerror === void 0 ? void 0 : onerror(_context.t0)) !== null && _onerror !== void 0 ? _onerror : retryInterval;
96
+ window.clearTimeout(retryTimer);
97
+ retryTimer = window.setTimeout(create, interval);
98
+ } catch (innerErr) {
99
+ // we should not retry anymore:
100
+ dispose();
101
+ reject(innerErr);
102
+ }
103
+ }
104
+ case 17:
105
+ case "end":
106
+ return _context.stop();
107
+ }
108
+ }, _callee, null, [[1, 14]]);
109
+ }));
110
+ return _create.apply(this, arguments);
111
+ }
112
+ create();
113
+ });
114
+ }
115
+ function defaultOnOpen(_x) {
116
+ return _defaultOnOpen.apply(this, arguments);
117
+ }
118
+ function _defaultOnOpen() {
119
+ _defaultOnOpen = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(response) {
120
+ var contentType;
121
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
122
+ while (1) switch (_context2.prev = _context2.next) {
123
+ case 0:
124
+ contentType = response.headers.get("content-type");
125
+ if (contentType !== null && contentType !== void 0 && contentType.startsWith(EventStreamContentType)) {
126
+ _context2.next = 3;
127
+ break;
128
+ }
129
+ throw new Error("Expected content-type to be ".concat(EventStreamContentType, ", Actual: ").concat(contentType));
130
+ case 3:
131
+ case "end":
132
+ return _context2.stop();
133
+ }
134
+ }, _callee2);
135
+ }));
136
+ return _defaultOnOpen.apply(this, arguments);
137
+ }
138
+
139
+ export { EventStreamContentType, fetchEventSource };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var fetch = require('./fetch.cjs');
4
+
5
+
6
+
7
+ exports.fetchEventSource = fetch.fetchEventSource;
@@ -0,0 +1,2 @@
1
+ import { fetchEventSource } from "./fetch";
2
+ export { fetchEventSource };
@@ -0,0 +1 @@
1
+ export { fetchEventSource } from './fetch.mjs';
@@ -0,0 +1,182 @@
1
+ 'use strict';
2
+
3
+ var _regeneratorRuntime = require('@babel/runtime/helpers/regeneratorRuntime');
4
+ var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
5
+
6
+ /**
7
+ * Converts a ReadableStream into a callback pattern.
8
+ * @param stream The input ReadableStream.
9
+ * @param onChunk A function that will be called on each new byte chunk in the stream.
10
+ * @returns {Promise<void>} A promise that will be resolved when the stream closes.
11
+ */
12
+ function getBytes(_x, _x2) {
13
+ return _getBytes.apply(this, arguments);
14
+ }
15
+ /**
16
+ * Parses arbitary byte chunks into EventSource line buffers.
17
+ * Each line should be of the format "field: value" and ends with \r, \n, or \r\n.
18
+ * @param onLine A function that will be called on each new EventSource line.
19
+ * @returns A function that should be called for each incoming byte chunk.
20
+ */
21
+ function _getBytes() {
22
+ _getBytes = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(stream, onChunk) {
23
+ var reader, result;
24
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
25
+ while (1) switch (_context.prev = _context.next) {
26
+ case 0:
27
+ if (stream) {
28
+ _context.next = 2;
29
+ break;
30
+ }
31
+ return _context.abrupt("return");
32
+ case 2:
33
+ reader = stream.getReader();
34
+ case 3:
35
+ _context.next = 5;
36
+ return reader.read();
37
+ case 5:
38
+ if ((result = _context.sent).done) {
39
+ _context.next = 9;
40
+ break;
41
+ }
42
+ onChunk(result.value);
43
+ _context.next = 3;
44
+ break;
45
+ case 9:
46
+ case "end":
47
+ return _context.stop();
48
+ }
49
+ }, _callee);
50
+ }));
51
+ return _getBytes.apply(this, arguments);
52
+ }
53
+ function getLines(onLine) {
54
+ var buffer;
55
+ var position; // current read position
56
+ var fieldLength; // length of the `field` portion of the line
57
+ var discardTrailingNewline = false;
58
+ // return a function that can process each incoming byte chunk:
59
+ return function onChunk(arr) {
60
+ if (buffer === undefined) {
61
+ buffer = arr;
62
+ position = 0;
63
+ fieldLength = -1;
64
+ } else {
65
+ // we're still parsing the old line. Append the new bytes into buffer:
66
+ buffer = concat(buffer, arr);
67
+ }
68
+ var bufLength = buffer.length;
69
+ var lineStart = 0; // index where the current line starts
70
+ while (position < bufLength) {
71
+ if (discardTrailingNewline) {
72
+ if (buffer[position] === 10 /* ControlChars.NewLine */) {
73
+ lineStart = ++position; // skip to next char
74
+ }
75
+ discardTrailingNewline = false;
76
+ }
77
+ // start looking forward till the end of line:
78
+ var lineEnd = -1; // index of the \r or \n char
79
+ for (; position < bufLength && lineEnd === -1; ++position) {
80
+ switch (buffer[position]) {
81
+ case 58 /* ControlChars.Colon */:
82
+ if (fieldLength === -1) {
83
+ // first colon in line
84
+ fieldLength = position - lineStart;
85
+ }
86
+ break;
87
+ // @ts-ignore:7029 \r case below should fallthrough to \n:
88
+ case 13 /* ControlChars.CarriageReturn */:
89
+ discardTrailingNewline = true;
90
+ case 10 /* ControlChars.NewLine */:
91
+ lineEnd = position;
92
+ break;
93
+ }
94
+ }
95
+ if (lineEnd === -1) {
96
+ // We reached the end of the buffer but the line hasn't ended.
97
+ // Wait for the next arr and then continue parsing:
98
+ break;
99
+ }
100
+ // we've reached the line end, send it out:
101
+ onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
102
+ lineStart = position; // we're now on the next line
103
+ fieldLength = -1;
104
+ }
105
+ if (lineStart === bufLength) {
106
+ buffer = undefined; // we've finished reading it
107
+ } else if (lineStart !== 0) {
108
+ // Create a new view into buffer beginning at lineStart so we don't
109
+ // need to copy over the previous lines when we get the new arr:
110
+ buffer = buffer.subarray(lineStart);
111
+ position -= lineStart;
112
+ }
113
+ };
114
+ }
115
+ /**
116
+ * Parses line buffers into EventSourceMessages.
117
+ * @param onId A function that will be called on each `id` field.
118
+ * @param onRetry A function that will be called on each `retry` field.
119
+ * @param onMessage A function that will be called on each message.
120
+ * @returns A function that should be called for each incoming line buffer.
121
+ */
122
+ function getMessages(onId, onRetry, onMessage) {
123
+ var message = newMessage();
124
+ var decoder = new TextDecoder();
125
+ // return a function that can process each incoming line buffer:
126
+ return function onLine(line, fieldLength) {
127
+ if (line.length === 0) {
128
+ // empty line denotes end of message. Trigger the callback and start a new message:
129
+ onMessage === null || onMessage === void 0 || onMessage(message);
130
+ message = newMessage();
131
+ } else if (fieldLength > 0) {
132
+ // exclude comments and lines with no values
133
+ // line is of format "<field>:<value>" or "<field>: <value>"
134
+ // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
135
+ var field = decoder.decode(line.subarray(0, fieldLength));
136
+ var valueOffset = fieldLength + (line[fieldLength + 1] === 32 /* ControlChars.Space */ ? 2 : 1);
137
+ var value = decoder.decode(line.subarray(valueOffset));
138
+ switch (field) {
139
+ case "data":
140
+ // if this message already has data, append the new value to the old.
141
+ // otherwise, just set to the new value:
142
+ message.data = message.data ? message.data + "\n" + value : value; // otherwise,
143
+ break;
144
+ case "event":
145
+ message.event = value;
146
+ break;
147
+ case "id":
148
+ onId(message.id = value);
149
+ break;
150
+ case "retry":
151
+ var retry = parseInt(value, 10);
152
+ if (!isNaN(retry)) {
153
+ // per spec, ignore non-integers
154
+ onRetry(message.retry = retry);
155
+ }
156
+ break;
157
+ }
158
+ }
159
+ };
160
+ }
161
+ function concat(a, b) {
162
+ var res = new Uint8Array(a.length + b.length);
163
+ res.set(a);
164
+ res.set(b, a.length);
165
+ return res;
166
+ }
167
+ function newMessage() {
168
+ // data, event, and id must be initialized to empty strings:
169
+ // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
170
+ // retry should be initialized to undefined so we return a consistent shape
171
+ // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways
172
+ return {
173
+ data: "",
174
+ event: "",
175
+ id: "",
176
+ retry: undefined
177
+ };
178
+ }
179
+
180
+ exports.getBytes = getBytes;
181
+ exports.getLines = getLines;
182
+ exports.getMessages = getMessages;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Represents a message sent in an event stream
3
+ * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format
4
+ */
5
+ export interface EventSourceMessage {
6
+ /** The event ID to set the EventSource object's last event ID value. */
7
+ id: string;
8
+ /** A string identifying the type of event described. */
9
+ event: string;
10
+ /** The event data */
11
+ data: string;
12
+ /** The reconnection interval (in milliseconds) to wait before retrying the connection */
13
+ retry?: number;
14
+ }
15
+ /**
16
+ * Converts a ReadableStream into a callback pattern.
17
+ * @param stream The input ReadableStream.
18
+ * @param onChunk A function that will be called on each new byte chunk in the stream.
19
+ * @returns {Promise<void>} A promise that will be resolved when the stream closes.
20
+ */
21
+ export declare function getBytes(stream: ReadableStream<Uint8Array> | null, onChunk: (arr: Uint8Array) => void): Promise<void>;
22
+ /**
23
+ * Parses arbitary byte chunks into EventSource line buffers.
24
+ * Each line should be of the format "field: value" and ends with \r, \n, or \r\n.
25
+ * @param onLine A function that will be called on each new EventSource line.
26
+ * @returns A function that should be called for each incoming byte chunk.
27
+ */
28
+ export declare function getLines(onLine: (line: Uint8Array, fieldLength: number) => void): (arr: Uint8Array) => void;
29
+ /**
30
+ * Parses line buffers into EventSourceMessages.
31
+ * @param onId A function that will be called on each `id` field.
32
+ * @param onRetry A function that will be called on each `retry` field.
33
+ * @param onMessage A function that will be called on each message.
34
+ * @returns A function that should be called for each incoming line buffer.
35
+ */
36
+ export declare function getMessages(onId: (id: string) => void, onRetry: (retry: number) => void, onMessage?: (msg: EventSourceMessage) => void): (line: Uint8Array, fieldLength: number) => void;
@@ -0,0 +1,178 @@
1
+ import _regeneratorRuntime from '@babel/runtime/helpers/regeneratorRuntime';
2
+ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
3
+
4
+ /**
5
+ * Converts a ReadableStream into a callback pattern.
6
+ * @param stream The input ReadableStream.
7
+ * @param onChunk A function that will be called on each new byte chunk in the stream.
8
+ * @returns {Promise<void>} A promise that will be resolved when the stream closes.
9
+ */
10
+ function getBytes(_x, _x2) {
11
+ return _getBytes.apply(this, arguments);
12
+ }
13
+ /**
14
+ * Parses arbitary byte chunks into EventSource line buffers.
15
+ * Each line should be of the format "field: value" and ends with \r, \n, or \r\n.
16
+ * @param onLine A function that will be called on each new EventSource line.
17
+ * @returns A function that should be called for each incoming byte chunk.
18
+ */
19
+ function _getBytes() {
20
+ _getBytes = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(stream, onChunk) {
21
+ var reader, result;
22
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
23
+ while (1) switch (_context.prev = _context.next) {
24
+ case 0:
25
+ if (stream) {
26
+ _context.next = 2;
27
+ break;
28
+ }
29
+ return _context.abrupt("return");
30
+ case 2:
31
+ reader = stream.getReader();
32
+ case 3:
33
+ _context.next = 5;
34
+ return reader.read();
35
+ case 5:
36
+ if ((result = _context.sent).done) {
37
+ _context.next = 9;
38
+ break;
39
+ }
40
+ onChunk(result.value);
41
+ _context.next = 3;
42
+ break;
43
+ case 9:
44
+ case "end":
45
+ return _context.stop();
46
+ }
47
+ }, _callee);
48
+ }));
49
+ return _getBytes.apply(this, arguments);
50
+ }
51
+ function getLines(onLine) {
52
+ var buffer;
53
+ var position; // current read position
54
+ var fieldLength; // length of the `field` portion of the line
55
+ var discardTrailingNewline = false;
56
+ // return a function that can process each incoming byte chunk:
57
+ return function onChunk(arr) {
58
+ if (buffer === undefined) {
59
+ buffer = arr;
60
+ position = 0;
61
+ fieldLength = -1;
62
+ } else {
63
+ // we're still parsing the old line. Append the new bytes into buffer:
64
+ buffer = concat(buffer, arr);
65
+ }
66
+ var bufLength = buffer.length;
67
+ var lineStart = 0; // index where the current line starts
68
+ while (position < bufLength) {
69
+ if (discardTrailingNewline) {
70
+ if (buffer[position] === 10 /* ControlChars.NewLine */) {
71
+ lineStart = ++position; // skip to next char
72
+ }
73
+ discardTrailingNewline = false;
74
+ }
75
+ // start looking forward till the end of line:
76
+ var lineEnd = -1; // index of the \r or \n char
77
+ for (; position < bufLength && lineEnd === -1; ++position) {
78
+ switch (buffer[position]) {
79
+ case 58 /* ControlChars.Colon */:
80
+ if (fieldLength === -1) {
81
+ // first colon in line
82
+ fieldLength = position - lineStart;
83
+ }
84
+ break;
85
+ // @ts-ignore:7029 \r case below should fallthrough to \n:
86
+ case 13 /* ControlChars.CarriageReturn */:
87
+ discardTrailingNewline = true;
88
+ case 10 /* ControlChars.NewLine */:
89
+ lineEnd = position;
90
+ break;
91
+ }
92
+ }
93
+ if (lineEnd === -1) {
94
+ // We reached the end of the buffer but the line hasn't ended.
95
+ // Wait for the next arr and then continue parsing:
96
+ break;
97
+ }
98
+ // we've reached the line end, send it out:
99
+ onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
100
+ lineStart = position; // we're now on the next line
101
+ fieldLength = -1;
102
+ }
103
+ if (lineStart === bufLength) {
104
+ buffer = undefined; // we've finished reading it
105
+ } else if (lineStart !== 0) {
106
+ // Create a new view into buffer beginning at lineStart so we don't
107
+ // need to copy over the previous lines when we get the new arr:
108
+ buffer = buffer.subarray(lineStart);
109
+ position -= lineStart;
110
+ }
111
+ };
112
+ }
113
+ /**
114
+ * Parses line buffers into EventSourceMessages.
115
+ * @param onId A function that will be called on each `id` field.
116
+ * @param onRetry A function that will be called on each `retry` field.
117
+ * @param onMessage A function that will be called on each message.
118
+ * @returns A function that should be called for each incoming line buffer.
119
+ */
120
+ function getMessages(onId, onRetry, onMessage) {
121
+ var message = newMessage();
122
+ var decoder = new TextDecoder();
123
+ // return a function that can process each incoming line buffer:
124
+ return function onLine(line, fieldLength) {
125
+ if (line.length === 0) {
126
+ // empty line denotes end of message. Trigger the callback and start a new message:
127
+ onMessage === null || onMessage === void 0 || onMessage(message);
128
+ message = newMessage();
129
+ } else if (fieldLength > 0) {
130
+ // exclude comments and lines with no values
131
+ // line is of format "<field>:<value>" or "<field>: <value>"
132
+ // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
133
+ var field = decoder.decode(line.subarray(0, fieldLength));
134
+ var valueOffset = fieldLength + (line[fieldLength + 1] === 32 /* ControlChars.Space */ ? 2 : 1);
135
+ var value = decoder.decode(line.subarray(valueOffset));
136
+ switch (field) {
137
+ case "data":
138
+ // if this message already has data, append the new value to the old.
139
+ // otherwise, just set to the new value:
140
+ message.data = message.data ? message.data + "\n" + value : value; // otherwise,
141
+ break;
142
+ case "event":
143
+ message.event = value;
144
+ break;
145
+ case "id":
146
+ onId(message.id = value);
147
+ break;
148
+ case "retry":
149
+ var retry = parseInt(value, 10);
150
+ if (!isNaN(retry)) {
151
+ // per spec, ignore non-integers
152
+ onRetry(message.retry = retry);
153
+ }
154
+ break;
155
+ }
156
+ }
157
+ };
158
+ }
159
+ function concat(a, b) {
160
+ var res = new Uint8Array(a.length + b.length);
161
+ res.set(a);
162
+ res.set(b, a.length);
163
+ return res;
164
+ }
165
+ function newMessage() {
166
+ // data, event, and id must be initialized to empty strings:
167
+ // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
168
+ // retry should be initialized to undefined so we return a consistent shape
169
+ // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways
170
+ return {
171
+ data: "",
172
+ event: "",
173
+ id: "",
174
+ retry: undefined
175
+ };
176
+ }
177
+
178
+ export { getBytes, getLines, getMessages };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var useMounted = require('./use-mounted.cjs');
5
+
6
+ /**
7
+ * @description
8
+ * fetch event source
9
+ */
10
+ var useEventSource = function useEventSource(url) {
11
+ var eventSourceRef = react.useRef();
12
+ useMounted.useMounted(function () {
13
+ var _eventSource = eventSourceRef.current = new EventSource(url);
14
+ return function () {
15
+ _eventSource.close();
16
+ };
17
+ });
18
+ };
19
+
20
+ exports.useEventSource = useEventSource;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @description
3
+ * fetch event source
4
+ */
5
+ declare const useEventSource: (url: string) => void;
6
+ export { useEventSource };
@@ -0,0 +1,18 @@
1
+ import { useRef } from 'react';
2
+ import { useMounted } from './use-mounted.mjs';
3
+
4
+ /**
5
+ * @description
6
+ * fetch event source
7
+ */
8
+ var useEventSource = function useEventSource(url) {
9
+ var eventSourceRef = useRef();
10
+ useMounted(function () {
11
+ var _eventSource = eventSourceRef.current = new EventSource(url);
12
+ return function () {
13
+ _eventSource.close();
14
+ };
15
+ });
16
+ };
17
+
18
+ export { useEventSource };
@@ -2,8 +2,8 @@
2
2
 
3
3
  var useStorageState = require('./use-storage-state.cjs');
4
4
 
5
- var useLocalStorageState = function useLocalStorageState(key, useBy) {
6
- return useStorageState.useStorageState(key, localStorage, useBy);
5
+ var useLocalStorageState = function useLocalStorageState(key, using) {
6
+ return useStorageState.useStorageState(key, globalThis.localStorage, using);
7
7
  };
8
8
 
9
9
  exports.useLocalStorageState = useLocalStorageState;
@@ -1,2 +1,2 @@
1
- import { type UseStorageStateBy } from "./use-storage-state";
2
- export declare const useLocalStorageState: (key: string, useBy?: UseStorageStateBy) => import("./use-storage-state").UsedStorageState;
1
+ import { type UsingStorageState } from "./use-storage-state";
2
+ export declare const useLocalStorageState: (key: string, using?: UsingStorageState) => import("./use-storage-state").UsedStorageState;
@@ -1,7 +1,7 @@
1
1
  import { useStorageState } from './use-storage-state.mjs';
2
2
 
3
- var useLocalStorageState = function useLocalStorageState(key, useBy) {
4
- return useStorageState(key, localStorage, useBy);
3
+ var useLocalStorageState = function useLocalStorageState(key, using) {
4
+ return useStorageState(key, globalThis.localStorage, using);
5
5
  };
6
6
 
7
7
  export { useLocalStorageState };
@@ -12,7 +12,6 @@ var useRaf = function useRaf(_callback) {
12
12
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
13
13
  timely = _ref.timely;
14
14
  var timed = react.useRef(null);
15
- var isTimed = react.useRef(false);
16
15
  useUnmount.useUnmount(function () {
17
16
  if (!timed.current) return;
18
17
  cancelAnimationFrame(timed.current);
@@ -21,14 +20,13 @@ var useRaf = function useRaf(_callback) {
21
20
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
22
21
  args[_key] = arguments[_key];
23
22
  }
24
- if (isTimed.current) return;
25
- isTimed.current = true;
23
+ if (timed.current) return;
26
24
  if (timely) {
27
25
  _callback.apply(void 0, args);
28
26
  return;
29
27
  }
30
28
  timed.current = requestAnimationFrame(function () {
31
- isTimed.current = false;
29
+ timed.current = null;
32
30
  _callback.apply(void 0, args);
33
31
  });
34
32
  });
@@ -10,7 +10,6 @@ var useRaf = function useRaf(_callback) {
10
10
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
11
11
  timely = _ref.timely;
12
12
  var timed = useRef(null);
13
- var isTimed = useRef(false);
14
13
  useUnmount(function () {
15
14
  if (!timed.current) return;
16
15
  cancelAnimationFrame(timed.current);
@@ -19,14 +18,13 @@ var useRaf = function useRaf(_callback) {
19
18
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
20
19
  args[_key] = arguments[_key];
21
20
  }
22
- if (isTimed.current) return;
23
- isTimed.current = true;
21
+ if (timed.current) return;
24
22
  if (timely) {
25
23
  _callback.apply(void 0, args);
26
24
  return;
27
25
  }
28
26
  timed.current = requestAnimationFrame(function () {
29
- isTimed.current = false;
27
+ timed.current = null;
30
28
  _callback.apply(void 0, args);
31
29
  });
32
30
  });
@@ -2,8 +2,8 @@
2
2
 
3
3
  var useStorageState = require('./use-storage-state.cjs');
4
4
 
5
- var useSessionStorageState = function useSessionStorageState(key, useBy) {
6
- return useStorageState.useStorageState(key, sessionStorage, useBy);
5
+ var useSessionStorageState = function useSessionStorageState(key, using) {
6
+ return useStorageState.useStorageState(key, sessionStorage, using);
7
7
  };
8
8
 
9
9
  exports.useSessionStorageState = useSessionStorageState;
@@ -1,2 +1,2 @@
1
- import { type UseStorageStateBy } from "./use-storage-state";
2
- export declare const useSessionStorageState: (key: string, useBy?: UseStorageStateBy) => import("./use-storage-state").UsedStorageState;
1
+ import { type UsingStorageState } from "./use-storage-state";
2
+ export declare const useSessionStorageState: (key: string, using?: UsingStorageState) => import("./use-storage-state").UsedStorageState;
@@ -1,7 +1,7 @@
1
1
  import { useStorageState } from './use-storage-state.mjs';
2
2
 
3
- var useSessionStorageState = function useSessionStorageState(key, useBy) {
4
- return useStorageState(key, sessionStorage, useBy);
3
+ var useSessionStorageState = function useSessionStorageState(key, using) {
4
+ return useStorageState(key, sessionStorage, using);
5
5
  };
6
6
 
7
7
  export { useSessionStorageState };
@@ -20,8 +20,10 @@ var useStorageState = function useStorageState(key, storage) {
20
20
  }, [key]);
21
21
  react.useEffect(function () {
22
22
  var onStorageChange = function onStorageChange(event) {
23
+ console.log("12321321321321321");
23
24
  if (event.key !== key) return;
24
25
  if (event.storageArea !== storage) return;
26
+ setState(event.newValue);
25
27
  };
26
28
  // only listen with flag = `true`
27
29
  if (listen) {
@@ -33,15 +35,13 @@ var useStorageState = function useStorageState(key, storage) {
33
35
  }, [listen]);
34
36
  // change handler
35
37
  var setter = react.useCallback(function (value) {
36
- if (listen) {
37
- if (isNull.isNull(value)) {
38
- storage.removeItem(key);
39
- } else {
40
- storage.setItem(key, value);
41
- }
38
+ // handler set, change state anytime
39
+ setState(value);
40
+ if (isNull.isNull(value)) {
41
+ storage.removeItem(key);
42
42
  return;
43
43
  }
44
- setState(value);
44
+ storage.setItem(key, value);
45
45
  }, [key, listen]);
46
46
  return [state, setter];
47
47
  };
@@ -1,5 +1,5 @@
1
1
  export type UsedStorageState = [string | null, (value: string | null) => void];
2
- export type UseStorageStateBy = {
2
+ export type UsingStorageState = {
3
3
  listen?: boolean;
4
4
  };
5
- export declare const useStorageState: (key: string, storage: Storage, { listen }?: UseStorageStateBy) => UsedStorageState;
5
+ export declare const useStorageState: (key: string, storage: Storage, { listen }?: UsingStorageState) => UsedStorageState;
@@ -18,8 +18,10 @@ var useStorageState = function useStorageState(key, storage) {
18
18
  }, [key]);
19
19
  useEffect(function () {
20
20
  var onStorageChange = function onStorageChange(event) {
21
+ console.log("12321321321321321");
21
22
  if (event.key !== key) return;
22
23
  if (event.storageArea !== storage) return;
24
+ setState(event.newValue);
23
25
  };
24
26
  // only listen with flag = `true`
25
27
  if (listen) {
@@ -31,15 +33,13 @@ var useStorageState = function useStorageState(key, storage) {
31
33
  }, [listen]);
32
34
  // change handler
33
35
  var setter = useCallback(function (value) {
34
- if (listen) {
35
- if (isNull(value)) {
36
- storage.removeItem(key);
37
- } else {
38
- storage.setItem(key, value);
39
- }
36
+ // handler set, change state anytime
37
+ setState(value);
38
+ if (isNull(value)) {
39
+ storage.removeItem(key);
40
40
  return;
41
41
  }
42
- setState(value);
42
+ storage.setItem(key, value);
43
43
  }, [key, listen]);
44
44
  return [state, setter];
45
45
  };
package/dist/index.cjs CHANGED
@@ -36,6 +36,7 @@ var useReactive = require('./hooks/use-reactive.cjs');
36
36
  var useParentSize = require('./hooks/use-parent-size.cjs');
37
37
  var useScreenSize = require('./hooks/use-screen-size.cjs');
38
38
  var useDrag = require('./hooks/use-drag.cjs');
39
+ var useEventSource = require('./hooks/use-event-source.cjs');
39
40
  var isRefable = require('./is/is-refable.cjs');
40
41
  var isUndefined = require('./is/is-undefined.cjs');
41
42
  var isNull = require('./is/is-null.cjs');
@@ -113,6 +114,7 @@ exports.useReactive = useReactive.useReactive;
113
114
  exports.useParentSize = useParentSize.useParentSize;
114
115
  exports.useScreenSize = useScreenSize.useScreenSize;
115
116
  exports.useDrag = useDrag.useDrag;
117
+ exports.useEventSource = useEventSource.useEventSource;
116
118
  exports.isRefable = isRefable.isRefable;
117
119
  exports.isUndefined = isUndefined.isUndefined;
118
120
  exports.isNull = isNull.isNull;
package/dist/index.d.ts CHANGED
@@ -38,6 +38,7 @@ export { useReactive } from "./hooks/use-reactive";
38
38
  export { useParentSize } from "./hooks/use-parent-size";
39
39
  export { useScreenSize } from "./hooks/use-screen-size";
40
40
  export { useDrag } from "./hooks/use-drag";
41
+ export { useEventSource } from "./hooks/use-event-source";
41
42
  /**
42
43
  * @description
43
44
  * is
package/dist/index.mjs CHANGED
@@ -34,6 +34,7 @@ export { useReactive } from './hooks/use-reactive.mjs';
34
34
  export { useParentSize } from './hooks/use-parent-size.mjs';
35
35
  export { useScreenSize } from './hooks/use-screen-size.mjs';
36
36
  export { useDrag } from './hooks/use-drag.mjs';
37
+ export { useEventSource } from './hooks/use-event-source.mjs';
37
38
  export { isRefable } from './is/is-refable.mjs';
38
39
  export { isUndefined } from './is/is-undefined.mjs';
39
40
  export { isNull } from './is/is-null.mjs';
@@ -7,4 +7,4 @@
7
7
  * @example
8
8
  * exclude([1, 2, 3, 4, 5], [2, 4]) // [1, 3, 5]
9
9
  */
10
- export declare const exclude: <T, E = unknown>(value: Array<T>, _excludeBy: Array<E>) => Array<Exclude<T, E>>;
10
+ export declare const exclude: <T, E = unknown>(value: Array<T>, _excludeBy: Array<E>) => (Exclude<T, E> extends never ? T : Exclude<T, E>)[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiszlab/relax",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "description": "react utils collection",
5
5
  "exports": {
6
6
  ".": {