@davidsouther/jiffies 1.0.0-beta.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.
Files changed (221) hide show
  1. package/README.md +60 -0
  2. package/build/assert.d.ts +23 -0
  3. package/build/assert.js +33 -0
  4. package/build/case.d.ts +1 -0
  5. package/build/case.js +5 -0
  6. package/build/components/button_bar.d.ts +8 -0
  7. package/build/components/button_bar.js +16 -0
  8. package/build/components/index.d.ts +1 -0
  9. package/build/components/index.js +1 -0
  10. package/build/components/inline_edit.d.ts +12 -0
  11. package/build/components/inline_edit.js +48 -0
  12. package/build/components/logger.d.ts +7 -0
  13. package/build/components/logger.js +22 -0
  14. package/build/components/select.d.ts +13 -0
  15. package/build/components/select.js +3 -0
  16. package/build/components/test.d.ts +1 -0
  17. package/build/components/test.js +2 -0
  18. package/build/components/virtual_scroll.d.ts +41 -0
  19. package/build/components/virtual_scroll.js +94 -0
  20. package/build/components/virtual_scroll.test.d.ts +1 -0
  21. package/build/components/virtual_scroll.test.js +21 -0
  22. package/build/context.d.ts +15 -0
  23. package/build/context.js +43 -0
  24. package/build/context.test.d.ts +1 -0
  25. package/build/context.test.js +46 -0
  26. package/build/debounce.d.ts +1 -0
  27. package/build/debounce.js +7 -0
  28. package/build/display.d.ts +5 -0
  29. package/build/display.js +3 -0
  30. package/build/dom/css/border.d.ts +11 -0
  31. package/build/dom/css/border.js +27 -0
  32. package/build/dom/css/constants.d.ts +31 -0
  33. package/build/dom/css/constants.js +28 -0
  34. package/build/dom/css/core.d.ts +5 -0
  35. package/build/dom/css/core.js +24 -0
  36. package/build/dom/css/fstyle.d.ts +5 -0
  37. package/build/dom/css/fstyle.js +32 -0
  38. package/build/dom/css/sizing.d.ts +5 -0
  39. package/build/dom/css/sizing.js +10 -0
  40. package/build/dom/dom.d.ts +27 -0
  41. package/build/dom/dom.js +94 -0
  42. package/build/dom/fc.d.ts +14 -0
  43. package/build/dom/fc.js +35 -0
  44. package/build/dom/fc.test.d.ts +1 -0
  45. package/build/dom/fc.test.js +21 -0
  46. package/build/dom/form/form.app.d.ts +1 -0
  47. package/build/dom/form/form.app.js +23 -0
  48. package/build/dom/form/form.d.ts +25 -0
  49. package/build/dom/form/form.js +25 -0
  50. package/build/dom/form/form.test.d.ts +0 -0
  51. package/build/dom/form/form.test.js +1 -0
  52. package/build/dom/html.d.ts +117 -0
  53. package/build/dom/html.js +114 -0
  54. package/build/dom/html.test.d.ts +1 -0
  55. package/build/dom/html.test.js +58 -0
  56. package/build/dom/router/link.d.ts +6 -0
  57. package/build/dom/router/link.js +3 -0
  58. package/build/dom/router/router.d.ts +12 -0
  59. package/build/dom/router/router.js +49 -0
  60. package/build/dom/svg.d.ts +64 -0
  61. package/build/dom/svg.js +65 -0
  62. package/build/dom/test.d.ts +1 -0
  63. package/build/dom/test.js +2 -0
  64. package/build/dom/types/css.d.ts +6612 -0
  65. package/build/dom/types/css.js +23 -0
  66. package/build/dom/types/dom.d.ts +0 -0
  67. package/build/dom/types/dom.js +1 -0
  68. package/build/dom/types/html.d.ts +616 -0
  69. package/build/dom/types/html.js +1 -0
  70. package/build/dom/xml.d.ts +1 -0
  71. package/build/dom/xml.js +5 -0
  72. package/build/equal.d.ts +4 -0
  73. package/build/equal.js +22 -0
  74. package/build/equal.test.d.ts +1 -0
  75. package/build/equal.test.js +20 -0
  76. package/build/flags.d.ts +7 -0
  77. package/build/flags.js +48 -0
  78. package/build/flags.test.d.ts +1 -0
  79. package/build/flags.test.js +35 -0
  80. package/build/generator.d.ts +1 -0
  81. package/build/generator.js +10 -0
  82. package/build/generator.test.d.ts +1 -0
  83. package/build/generator.test.js +24 -0
  84. package/build/index.d.ts +13 -0
  85. package/build/index.js +13 -0
  86. package/build/is_browser.d.ts +1 -0
  87. package/build/is_browser.js +1 -0
  88. package/build/loader.d.mts +22 -0
  89. package/build/loader.mjs +35 -0
  90. package/build/lock.d.ts +1 -0
  91. package/build/lock.js +23 -0
  92. package/build/lock.test.d.ts +1 -0
  93. package/build/lock.test.js +16 -0
  94. package/build/log.d.ts +26 -0
  95. package/build/log.js +34 -0
  96. package/build/parcel_resolver.d.ts +3 -0
  97. package/build/parcel_resolver.js +19 -0
  98. package/build/range.d.ts +1 -0
  99. package/build/range.js +7 -0
  100. package/build/result.d.ts +31 -0
  101. package/build/result.js +65 -0
  102. package/build/result.test.d.ts +1 -0
  103. package/build/result.test.js +71 -0
  104. package/build/safe.d.ts +1 -0
  105. package/build/safe.js +10 -0
  106. package/build/scope/describe.d.ts +14 -0
  107. package/build/scope/describe.js +52 -0
  108. package/build/scope/display/console.d.ts +2 -0
  109. package/build/scope/display/console.js +21 -0
  110. package/build/scope/display/dom.d.ts +3 -0
  111. package/build/scope/display/dom.js +26 -0
  112. package/build/scope/display/junit.d.ts +2 -0
  113. package/build/scope/display/junit.js +17 -0
  114. package/build/scope/execute.d.ts +12 -0
  115. package/build/scope/execute.js +85 -0
  116. package/build/scope/expect.d.ts +23 -0
  117. package/build/scope/expect.js +107 -0
  118. package/build/scope/fix.d.ts +4 -0
  119. package/build/scope/fix.js +22 -0
  120. package/build/scope/index.d.ts +3 -0
  121. package/build/scope/index.js +3 -0
  122. package/build/scope/scope.d.ts +17 -0
  123. package/build/scope/scope.js +1 -0
  124. package/build/server/http/apps.d.ts +5 -0
  125. package/build/server/http/apps.js +23 -0
  126. package/build/server/http/index.d.ts +21 -0
  127. package/build/server/http/index.js +71 -0
  128. package/build/server/http/response.d.ts +4 -0
  129. package/build/server/http/response.js +37 -0
  130. package/build/server/http/sitemap.d.ts +2 -0
  131. package/build/server/http/sitemap.js +42 -0
  132. package/build/server/http/static.d.ts +2 -0
  133. package/build/server/http/static.js +21 -0
  134. package/build/server/http/typescript.d.ts +5 -0
  135. package/build/server/http/typescript.js +40 -0
  136. package/build/server/main.d.ts +2 -0
  137. package/build/server/main.js +9 -0
  138. package/build/test.d.mts +2 -0
  139. package/build/test.mjs +23 -0
  140. package/build/test_all.d.ts +1 -0
  141. package/build/test_all.js +19 -0
  142. package/build/transpile.d.mts +3 -0
  143. package/build/transpile.mjs +18 -0
  144. package/package.json +36 -0
  145. package/src/404.html +14 -0
  146. package/src/assert.ts +50 -0
  147. package/src/case.ts +5 -0
  148. package/src/components/_notes +33 -0
  149. package/src/components/button_bar.ts +38 -0
  150. package/src/components/inline_edit.ts +77 -0
  151. package/src/components/logger.ts +36 -0
  152. package/src/components/select.ts +22 -0
  153. package/src/components/test.js +2 -0
  154. package/src/components/virtual_scroll.test.ts +27 -0
  155. package/src/components/virtual_scroll.ts +194 -0
  156. package/src/context.test.ts +58 -0
  157. package/src/context.ts +62 -0
  158. package/src/debounce.ts +7 -0
  159. package/src/display.ts +12 -0
  160. package/src/dom/README.md +102 -0
  161. package/src/dom/css/border.ts +47 -0
  162. package/src/dom/css/constants.ts +34 -0
  163. package/src/dom/css/core.ts +28 -0
  164. package/src/dom/css/fstyle.ts +42 -0
  165. package/src/dom/css/sizing.ts +11 -0
  166. package/src/dom/dom.ts +153 -0
  167. package/src/dom/fc.test.ts +43 -0
  168. package/src/dom/fc.ts +79 -0
  169. package/src/dom/form/form.app.ts +50 -0
  170. package/src/dom/form/form.test.ts +0 -0
  171. package/src/dom/form/form.ts +53 -0
  172. package/src/dom/form/index.html +14 -0
  173. package/src/dom/html.test.ts +72 -0
  174. package/src/dom/html.ts +129 -0
  175. package/src/dom/router/link.ts +14 -0
  176. package/src/dom/router/router.ts +69 -0
  177. package/src/dom/svg.ts +77 -0
  178. package/src/dom/test.ts +2 -0
  179. package/src/dom/types/css.ts +10106 -0
  180. package/src/dom/types/dom.ts +0 -0
  181. package/src/dom/types/html.ts +631 -0
  182. package/src/dom/xml.ts +12 -0
  183. package/src/equal.test.ts +23 -0
  184. package/src/equal.ts +32 -0
  185. package/src/favicon.ico +0 -0
  186. package/src/flags.test.ts +43 -0
  187. package/src/flags.ts +53 -0
  188. package/src/generator.test.ts +26 -0
  189. package/src/generator.ts +12 -0
  190. package/src/hooks/_notes +3 -0
  191. package/src/index.html +79 -0
  192. package/src/is_browser.js +1 -0
  193. package/src/loader.mjs +45 -0
  194. package/src/lock.test.ts +17 -0
  195. package/src/lock.ts +22 -0
  196. package/src/log.ts +61 -0
  197. package/src/observable/_notes +13 -0
  198. package/src/observable/observable._js +175 -0
  199. package/src/range.ts +7 -0
  200. package/src/result.test.ts +98 -0
  201. package/src/result.ts +107 -0
  202. package/src/safe.ts +12 -0
  203. package/src/scope/describe.ts +70 -0
  204. package/src/scope/display/console.ts +26 -0
  205. package/src/scope/display/dom.ts +36 -0
  206. package/src/scope/display/junit.ts +67 -0
  207. package/src/scope/execute.ts +108 -0
  208. package/src/scope/expect.ts +170 -0
  209. package/src/scope/fix.ts +29 -0
  210. package/src/scope/index.ts +11 -0
  211. package/src/scope/scope.ts +21 -0
  212. package/src/server/http/apps.ts +26 -0
  213. package/src/server/http/index.ts +119 -0
  214. package/src/server/http/response.ts +47 -0
  215. package/src/server/http/sitemap.ts +48 -0
  216. package/src/server/http/static.ts +27 -0
  217. package/src/server/http/typescript.ts +46 -0
  218. package/src/server/main.ts +13 -0
  219. package/src/test.mjs +29 -0
  220. package/src/test_all.ts +22 -0
  221. package/src/transpile.mjs +29 -0
@@ -0,0 +1,7 @@
1
+ export declare const parse: (parseArgs: string[]) => {
2
+ readonly argv0: string;
3
+ readonly args: readonly string[];
4
+ get(flag: string, def?: boolean): boolean;
5
+ asNumber(param: string, def?: number): number;
6
+ asString(param: string, def?: string): string;
7
+ };
package/build/flags.js ADDED
@@ -0,0 +1,48 @@
1
+ export const parse = (parseArgs) => {
2
+ const fromNode = parseArgs[0].endsWith("node");
3
+ const argv = parseArgs[fromNode ? 1 : 0];
4
+ const params = new Map();
5
+ const flags = new Map();
6
+ const args = [];
7
+ let index = fromNode ? 2 : 1;
8
+ const hasNext = () => index < parseArgs.length;
9
+ const peek = () => parseArgs[index];
10
+ const advance = () => parseArgs[index++];
11
+ const parseLong = (arg) => {
12
+ if (arg.substr(0, 3) === "no-") {
13
+ flags.set(arg.substr(3), false);
14
+ }
15
+ else if (!arg.includes("=")) {
16
+ flags.set(arg, true);
17
+ }
18
+ else {
19
+ const [param, ...value] = arg.split("=");
20
+ params.set(param, value.join("="));
21
+ }
22
+ };
23
+ while (hasNext()) {
24
+ if (peek().substr(0, 2) == "--") {
25
+ parseLong(advance().substr(2));
26
+ }
27
+ else {
28
+ args.push(advance());
29
+ }
30
+ }
31
+ return {
32
+ get argv0() {
33
+ return argv;
34
+ },
35
+ get args() {
36
+ return args;
37
+ },
38
+ get(flag, def = false) {
39
+ return flags.get(flag) ?? def;
40
+ },
41
+ asNumber(param, def = 0) {
42
+ return Number.parseFloat(params.get(param) ?? `${def}`);
43
+ },
44
+ asString(param, def = "") {
45
+ return params.get(param) ?? def;
46
+ },
47
+ };
48
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ import { describe, it, expect } from "./scope/index.js";
2
+ import { parse } from "./flags.js";
3
+ const TEST_CASES = {
4
+ SIMPLE: "program",
5
+ NODE: "/usr/local/bin/node program",
6
+ ONE_FLAG: "program --fun",
7
+ ONE_PARAM: "program --fun=100",
8
+ ONE_ARG: "program cat",
9
+ ONE_NO_FLAG: "program --no-fun",
10
+ MIXED: "program --fun=dog cat --port=8080 mouse --hamster --no-bird",
11
+ };
12
+ const makeFlags = (commandLine) => {
13
+ return parse(commandLine.split(" "));
14
+ };
15
+ describe("Flags", () => {
16
+ it("stores the program name", () => {
17
+ const flags = makeFlags(TEST_CASES.SIMPLE);
18
+ expect(flags.argv0).toEqual("program");
19
+ expect(flags.args).toEqual([]);
20
+ });
21
+ it("stores the program name ignoring node", () => {
22
+ const flags = makeFlags(TEST_CASES.NODE);
23
+ expect(flags.argv0).toEqual("program");
24
+ expect(flags.args).toEqual([]);
25
+ });
26
+ it("parses a flag", () => {
27
+ const flags = makeFlags(TEST_CASES.ONE_FLAG);
28
+ expect(flags.get("fun")).toBe(true);
29
+ });
30
+ it("parses a flag with a default value", () => {
31
+ const flags = makeFlags(TEST_CASES.SIMPLE);
32
+ expect(flags.get("missing")).toBe(false);
33
+ expect(flags.get("missing", true)).toBe(true);
34
+ });
35
+ });
@@ -0,0 +1 @@
1
+ export declare function takeWhile<T>(predicate: (t: T) => boolean, iterator: Iterable<T>): Generator<T, void, unknown>;
@@ -0,0 +1,10 @@
1
+ export function* takeWhile(predicate, iterator) {
2
+ for (const x of iterator) {
3
+ if (predicate(x)) {
4
+ yield x;
5
+ }
6
+ else {
7
+ return;
8
+ }
9
+ }
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { takeWhile } from "./generator.js";
2
+ import { describe, it, expect } from "./scope/index.js";
3
+ describe("Generator", () => {
4
+ it("takes from a generator until a predicate", () => {
5
+ const generator = function* () {
6
+ let i = 1;
7
+ while (true) {
8
+ yield (i = i * 2);
9
+ }
10
+ };
11
+ const filter = () => {
12
+ let previousValue = 0;
13
+ return (n) => {
14
+ if (previousValue < 100) {
15
+ previousValue = n;
16
+ return true;
17
+ }
18
+ return false;
19
+ };
20
+ };
21
+ const values = [...takeWhile(filter(), generator())];
22
+ expect(values).toEqual([2, 4, 8, 16, 32, 64, 128]);
23
+ });
24
+ });
@@ -0,0 +1,13 @@
1
+ export * as assert from "./assert";
2
+ export * as case from "./case";
3
+ export * as context from "./context";
4
+ export * as debounce from "./debounce";
5
+ export * as display from "./display";
6
+ export * as equal from "./equal";
7
+ export * as generator from "./generator";
8
+ export * as lock from "./lock";
9
+ export * as range from "./range";
10
+ export * as result from "./result";
11
+ export * as safe from "./safe";
12
+ export * as components from "./components";
13
+ export * as dom from "./dom/dom";
package/build/index.js ADDED
@@ -0,0 +1,13 @@
1
+ export * as assert from "./assert";
2
+ export * as case from "./case";
3
+ export * as context from "./context";
4
+ export * as debounce from "./debounce";
5
+ export * as display from "./display";
6
+ export * as equal from "./equal";
7
+ export * as generator from "./generator";
8
+ export * as lock from "./lock";
9
+ export * as range from "./range";
10
+ export * as result from "./result";
11
+ export * as safe from "./safe";
12
+ export * as components from "./components";
13
+ export * as dom from "./dom/dom";
@@ -0,0 +1 @@
1
+ export const IsBrowser: boolean;
@@ -0,0 +1 @@
1
+ export const IsBrowser = typeof window !== "undefined";
@@ -0,0 +1,22 @@
1
+ /** @returns {Promise<{url: string}>} */
2
+ export function resolve(specifier: string, context: {
3
+ parentURL?: string;
4
+ }, defaultResolve: (specifier: string, context: {
5
+ parentURL?: string;
6
+ }, defaultResolve: Function) => Promise<{
7
+ url: string;
8
+ }>): Promise<{
9
+ url: string;
10
+ }>;
11
+ /** @returns {Promise<{format: string, source: string}>} */
12
+ export function load(url: string, context: {
13
+ format?: string;
14
+ }, defaultLoad: (url: string, context: {
15
+ format?: string;
16
+ }, defaultLoad?: Function) => Promise<{
17
+ format: string;
18
+ source: string;
19
+ }>): Promise<{
20
+ format: string;
21
+ source: string;
22
+ }>;
@@ -0,0 +1,35 @@
1
+ import { stat } from "node:fs/promises";
2
+ import { cwd } from "node:process";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { transpile } from "./transpile.mjs";
5
+ const baseURL = pathToFileURL(`${cwd()}/`).href;
6
+ /** @returns {Promise<{url: string}>} */
7
+ export async function resolve(
8
+ /** @type string */ specifier,
9
+ /** @type {{parentURL?: string}} */ context,
10
+ /** @type {(specifier: string, context: {parentURL?: string}, defaultResolve: Function) => Promise<{url: string}>} */ defaultResolve) {
11
+ const tsURL = new URL(specifier.replace(/js$/, "ts"), context.parentURL ?? baseURL);
12
+ const tsSpecifier = tsURL.href;
13
+ try {
14
+ const stats = await stat(fileURLToPath(tsURL));
15
+ if (stats.isFile()) {
16
+ return { url: tsSpecifier };
17
+ }
18
+ }
19
+ catch (e) {
20
+ // Do nothing
21
+ }
22
+ return defaultResolve(specifier, context, defaultResolve);
23
+ }
24
+ /** @returns {Promise<{format: string, source: string}>} */
25
+ export async function load(
26
+ /** @type string */ url,
27
+ /** @type {{format?: string}} */ context,
28
+ /** @type {(url: string, context: {format?: string}, defaultLoad?: Function) => Promise<{format: string, source: string}>} */ defaultLoad) {
29
+ return url.endsWith("ts")
30
+ ? {
31
+ format: "module",
32
+ source: await transpile(url, async () => (await defaultLoad(url, { format: "module" })).source),
33
+ }
34
+ : defaultLoad(url, context, defaultLoad);
35
+ }
@@ -0,0 +1 @@
1
+ export declare function lock(fn: Function): Function;
package/build/lock.js ADDED
@@ -0,0 +1,23 @@
1
+ const locks = new WeakSet();
2
+ export function lock(fn) {
3
+ return function (...args) {
4
+ let ret = null;
5
+ let ex = null;
6
+ if (!locks.has(fn)) {
7
+ locks.add(fn);
8
+ try {
9
+ ret = fn(...args);
10
+ }
11
+ catch (e) {
12
+ ex = e;
13
+ }
14
+ }
15
+ locks.delete(fn);
16
+ if (ex !== null) {
17
+ throw ex;
18
+ }
19
+ else {
20
+ return ret;
21
+ }
22
+ };
23
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import { describe, it, expect } from "./scope/index.js";
2
+ import { lock } from "./lock.js";
3
+ describe("Lock", () => {
4
+ it("prevents reentry", function () {
5
+ let count = 0;
6
+ const inc = lock(function () {
7
+ if (count > 4) {
8
+ return;
9
+ }
10
+ inc();
11
+ count++;
12
+ });
13
+ inc();
14
+ expect(count).toBe(1);
15
+ });
16
+ });
package/build/log.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { Display } from "./display.js";
2
+ export interface Log {
3
+ (message: Display, data?: {}): void;
4
+ }
5
+ export interface Logger {
6
+ level: Number;
7
+ debug: Log;
8
+ info: Log;
9
+ warn: Log;
10
+ error: Log;
11
+ }
12
+ export declare const LEVEL: {
13
+ UNKNOWN: number;
14
+ SILENT: number;
15
+ DEBUG: number;
16
+ VERBOSE: number;
17
+ INFO: number;
18
+ WARN: number;
19
+ ERROR: number;
20
+ };
21
+ export declare function getLogger(name: string): Logger;
22
+ export declare const DEFAULT_LOGGER: Logger;
23
+ export declare function debug(message: Display, data?: {}): void;
24
+ export declare function info(message: Display, data?: {}): void;
25
+ export declare function warn(message: Display, data?: {}): void;
26
+ export declare function error(message: Display, data?: {}): void;
package/build/log.js ADDED
@@ -0,0 +1,34 @@
1
+ import { display } from "./display.js";
2
+ export const LEVEL = {
3
+ UNKNOWN: 0,
4
+ SILENT: 0,
5
+ DEBUG: 1,
6
+ VERBOSE: 1,
7
+ INFO: 2,
8
+ WARN: 3,
9
+ ERROR: 4,
10
+ };
11
+ export function getLogger(name) {
12
+ const logger = { level: LEVEL.INFO };
13
+ const logAt = (level, fn) => (message, data) => level >= (logger.level ?? LEVEL.SILENT)
14
+ ? fn(display(message), data)
15
+ : undefined;
16
+ logger.debug = logAt(LEVEL.VERBOSE, console.debug.bind(console));
17
+ logger.info = logAt(LEVEL.INFO, console.info.bind(console));
18
+ logger.warn = logAt(LEVEL.WARN, console.warn.bind(console));
19
+ logger.error = logAt(LEVEL.ERROR, console.error.bind(console));
20
+ return logger;
21
+ }
22
+ export const DEFAULT_LOGGER = getLogger("default");
23
+ export function debug(message, data) {
24
+ DEFAULT_LOGGER.debug(message, data);
25
+ }
26
+ export function info(message, data) {
27
+ DEFAULT_LOGGER.info(message, data);
28
+ }
29
+ export function warn(message, data) {
30
+ DEFAULT_LOGGER.warn(message, data);
31
+ }
32
+ export function error(message, data) {
33
+ DEFAULT_LOGGER.error(message, data);
34
+ }
@@ -0,0 +1,3 @@
1
+ declare const _default: Resolver;
2
+ export default _default;
3
+ import { Resolver } from "@parcel/plugin";
@@ -0,0 +1,19 @@
1
+ import { Resolver } from "@parcel/plugin";
2
+ export default new Resolver({
3
+ async resolve({ specifier }) {
4
+ console.log(specifier);
5
+ // const tsURL = new URL(
6
+ // specifier.replace(/js$/, "ts"),
7
+ // );
8
+ // const tsSpecifier = tsURL.href;
9
+ // try {
10
+ // const stats = await stat(fileURLToPath(tsURL));
11
+ // if (stats.isFile()) {
12
+ // return { url: tsSpecifier };
13
+ // }
14
+ // } catch (e) {
15
+ // // Do nothing
16
+ // }
17
+ return null;
18
+ },
19
+ });
@@ -0,0 +1 @@
1
+ export declare function range(start: number, end: number, stride?: number): number[];
package/build/range.js ADDED
@@ -0,0 +1,7 @@
1
+ export function range(start, end, stride = 1) {
2
+ const range = [];
3
+ for (let i = start; i < end; i += stride) {
4
+ range.push(i);
5
+ }
6
+ return range;
7
+ }
@@ -0,0 +1,31 @@
1
+ export declare type None = null;
2
+ export declare type Some<T> = T;
3
+ export declare type Option<T> = Some<T> | None;
4
+ export declare type Err<E extends Error> = {
5
+ err: E;
6
+ map: <U>(fn: (t: unknown) => Result<U>) => Result<U>;
7
+ };
8
+ export declare type Ok<T> = {
9
+ ok: T;
10
+ map: <U>(fn: (t: T) => Result<U>) => Result<U>;
11
+ };
12
+ export declare type Result<T, E extends Error = Error> = Ok<T> | Err<E>;
13
+ export declare const isNone: <T>(s: Option<T>) => s is null;
14
+ export declare const isSome: <T>(s: Option<T>) => s is T;
15
+ export declare function None<T = unknown>(_?: T): Option<T>;
16
+ export declare function Some<T>(t: Option<T>): Option<T>;
17
+ export declare function Some<T>(t: T): Option<T>;
18
+ export declare const isOk: <T, E extends Error>(t: Result<T, E>) => t is Ok<T>;
19
+ export declare const isErr: <T, E extends Error>(e: Result<T, E>) => boolean;
20
+ export declare const isResult: <T, E extends Error>(t: Result<T, E>) => t is Result<T, E>;
21
+ export declare function Ok<T>(ok: Ok<T>): T;
22
+ export declare function Ok<T>(t: T): Ok<T>;
23
+ export declare function Err<E extends Error>(e: Err<E>): E;
24
+ export declare function Err<E extends Error>(e: E): Err<E>;
25
+ export declare function Err<E extends Error>(e: string): Err<E>;
26
+ export declare function unwrap<T, E extends Error>(result: Result<T, E>): T | never;
27
+ export declare function unwrap<O>(some: Option<O>): O | never;
28
+ export declare function unwrapOr<T, E extends Error>(result: Result<T, E>, def: T): T;
29
+ export declare function unwrapOr<T>(some: Some<T>, def: T): T;
30
+ export declare function unwrapOrElse<T, E extends Error>(result: Result<T, Error>, def: () => T): T;
31
+ export declare function unwrapOrElse<T>(some: Some<T>, def: () => T): T;
@@ -0,0 +1,65 @@
1
+ export const isNone = (s) => s == null;
2
+ export const isSome = (s) => s != null;
3
+ export function None(_) {
4
+ return null;
5
+ }
6
+ export function Some(t) {
7
+ return t;
8
+ }
9
+ export const isOk = (t) => t.ok !== undefined;
10
+ export const isErr = (e) => e.err !== undefined;
11
+ export const isResult = (t) => isOk(t) || isErr(t);
12
+ export function Ok(t) {
13
+ return t.ok
14
+ ? t.ok
15
+ : {
16
+ ok: t,
17
+ map(fn) {
18
+ return fn(Ok(this));
19
+ },
20
+ };
21
+ }
22
+ export function Err(e) {
23
+ return (e.err ?? {
24
+ err: typeof e === "string" ? new Error(e) : e,
25
+ map(fn) {
26
+ return this;
27
+ },
28
+ });
29
+ }
30
+ export function unwrap(t) {
31
+ if (isNone(t)) {
32
+ throw new Error(`Attempted to unwrap None`);
33
+ }
34
+ if (isErr(t)) {
35
+ throw Err(t);
36
+ }
37
+ if (isOk(t)) {
38
+ return Ok(t);
39
+ }
40
+ return t;
41
+ }
42
+ export function unwrapOr(t, def) {
43
+ if (isNone(t)) {
44
+ return def;
45
+ }
46
+ if (isErr(t)) {
47
+ return def;
48
+ }
49
+ if (isOk(t)) {
50
+ return Ok(t);
51
+ }
52
+ return t;
53
+ }
54
+ export function unwrapOrElse(t, def) {
55
+ if (isNone(t)) {
56
+ return def();
57
+ }
58
+ if (isErr(t)) {
59
+ return def();
60
+ }
61
+ if (isOk(t)) {
62
+ return Ok(t);
63
+ }
64
+ return t;
65
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,71 @@
1
+ import { Err, None, Ok, Some, unwrap, unwrapOr, unwrapOrElse, } from "./result.js";
2
+ import { describe, it } from "./scope/describe.js";
3
+ import { expect } from "./scope/expect.js";
4
+ describe("Result", () => {
5
+ it("converts Nones", () => {
6
+ const a = None();
7
+ expect(a).toBeNull();
8
+ const b = None();
9
+ expect(b).toBeNull();
10
+ const c = Some(a);
11
+ expect(c).toBeNull();
12
+ const d = Some(b);
13
+ expect(d).toBeNull();
14
+ });
15
+ it("converts Somes", () => {
16
+ const a = Some("a");
17
+ expect(a).toBe("a");
18
+ const b = Some(a);
19
+ expect(b).toBe("a");
20
+ });
21
+ it("converts Errs", () => {
22
+ const a = Err(new Error("a error"));
23
+ const b = Err(a);
24
+ expect(b).toMatchObject({ message: "a error" });
25
+ // Assign Err to Result
26
+ const c = a;
27
+ });
28
+ it("converts Oks", () => {
29
+ const a = Ok("a ok");
30
+ const b = Ok(a);
31
+ expect(b).toBe("a ok");
32
+ // Assign ok to Result
33
+ const c = a;
34
+ });
35
+ it("unwraps", () => {
36
+ const a = Some("some");
37
+ const b = None();
38
+ const c = Ok("ok");
39
+ const d = Err(new Error("err"));
40
+ const e = "else";
41
+ expect(unwrap(a)).toBe("some");
42
+ expect(unwrap(c)).toBe("ok");
43
+ expect(() => unwrap(b)).toThrow("Attempted to unwrap None");
44
+ expect(() => unwrap(d)).toThrow("err");
45
+ expect(unwrap(e)).toBe("else");
46
+ });
47
+ it("unwrapsOrs", () => {
48
+ const a = Some("some");
49
+ const b = None();
50
+ const c = Ok("ok");
51
+ const d = Err(new Error("err"));
52
+ const e = "else";
53
+ expect(unwrapOr(a, "z")).toBe("some");
54
+ expect(unwrapOr(c, "z")).toBe("ok");
55
+ expect(unwrapOr(b, "z")).toBe("z");
56
+ expect(unwrapOr(d, "z")).toBe("z");
57
+ expect(unwrapOr(e, "z")).toBe("else");
58
+ });
59
+ it("unwrapsOrElse", () => {
60
+ const a = Some("some");
61
+ const b = None();
62
+ const c = Ok("ok");
63
+ const d = Err(new Error("err"));
64
+ const e = "else";
65
+ expect(unwrapOrElse(a, () => "z")).toBe("some");
66
+ expect(unwrapOrElse(c, () => "z")).toBe("ok");
67
+ expect(unwrapOrElse(b, () => "z")).toBe("z");
68
+ expect(unwrapOrElse(d, () => "z")).toBe("z");
69
+ expect(unwrapOrElse(e, () => "z")).toBe("else");
70
+ });
71
+ });
@@ -0,0 +1 @@
1
+ export declare const safe: <A extends unknown[], R>(fn: (...args: A) => R, r: R) => (...args: A) => R;
package/build/safe.js ADDED
@@ -0,0 +1,10 @@
1
+ import { error } from "./log.js";
2
+ export const safe = (fn, r) => (...args) => {
3
+ try {
4
+ return fn(...args);
5
+ }
6
+ catch (e) {
7
+ error(`${e}`);
8
+ return r;
9
+ }
10
+ };
@@ -0,0 +1,14 @@
1
+ import { TestCase } from "./scope.js";
2
+ export declare const beforeall: unique symbol;
3
+ export declare const beforeeach: unique symbol;
4
+ export declare const afterall: unique symbol;
5
+ export declare const aftereach: unique symbol;
6
+ export declare function rootCases(): TestCase;
7
+ export declare function getTotalCases(): number;
8
+ export declare function describe(title: string, block: Function): void;
9
+ export declare function it(title: string, block: Function): void;
10
+ export declare function beforeEach(fn: () => void): void;
11
+ export declare function beforeAll(fn: () => void): void;
12
+ export declare function afterEach(fn: () => void): void;
13
+ export declare function afterAll(fn: () => void): void;
14
+ export declare function cleanState<State extends {}>(init: () => State, runner?: (action: () => void) => void): State;
@@ -0,0 +1,52 @@
1
+ import { getLogger } from "../log.js";
2
+ export const beforeall = Symbol("beforeAll");
3
+ export const beforeeach = Symbol("beforeEach");
4
+ export const afterall = Symbol("afterAll");
5
+ export const aftereach = Symbol("afterEach");
6
+ const logger = getLogger("scope");
7
+ const CASES = {};
8
+ let cases = [CASES];
9
+ let totalCases = 0;
10
+ function push(title) {
11
+ const next = (cases[0][title] = {});
12
+ cases.unshift(next);
13
+ }
14
+ function pop() {
15
+ cases.shift();
16
+ }
17
+ export function rootCases() {
18
+ return CASES;
19
+ }
20
+ export function getTotalCases() {
21
+ return totalCases;
22
+ }
23
+ export function describe(title, block) {
24
+ logger.debug(`describe(${title})`);
25
+ push(title);
26
+ block();
27
+ pop();
28
+ }
29
+ export function it(title, block) {
30
+ logger.debug(`it(${title})`);
31
+ totalCases += 1;
32
+ cases[0][title] = block;
33
+ }
34
+ export function beforeEach(fn) {
35
+ cases[0][beforeeach] = fn;
36
+ }
37
+ export function beforeAll(fn) {
38
+ cases[0][beforeall] = fn;
39
+ }
40
+ export function afterEach(fn) {
41
+ cases[0][aftereach] = fn;
42
+ }
43
+ export function afterAll(fn) {
44
+ cases[0][afterall] = fn;
45
+ }
46
+ export function cleanState(init, runner = beforeEach) {
47
+ const state = {};
48
+ runner(() => {
49
+ Object.assign(state, init());
50
+ });
51
+ return state;
52
+ }
@@ -0,0 +1,2 @@
1
+ import { TestResult } from "../scope.js";
2
+ export declare function onConsole(results: TestResult): void;
@@ -0,0 +1,21 @@
1
+ import { getLogger } from "../../log.js";
2
+ import { getTotalCases } from "../describe.js";
3
+ import { flattenResults } from "../execute.js";
4
+ const logger = getLogger("Scope Test Runner");
5
+ export function onConsole(results) {
6
+ const { executed, failed } = results;
7
+ logger.info("Executed test suite.", {
8
+ executed,
9
+ total: getTotalCases(),
10
+ failed,
11
+ });
12
+ const flat = flattenResults(results);
13
+ for (const { test } of flat) {
14
+ logger.debug(test);
15
+ }
16
+ for (const { test, stack } of flat) {
17
+ if (stack) {
18
+ logger.error(test, { stack });
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,3 @@
1
+ import { DOMElement, Updatable } from "../../dom/dom.js";
2
+ import { TestResult } from "../scope.js";
3
+ export declare function displayStatistics(results: TestResult, root?: Updatable<DOMElement>): void;