workclock 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Karthik P
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE ADDED
@@ -0,0 +1,28 @@
1
+ workclock
2
+ Copyright (c) 2026 Karthik P
3
+
4
+ Parts of the test suite are ported from businesstimedelta
5
+ (https://github.com/seppemans/businesstimedelta), which is distributed
6
+ under the following license:
7
+
8
+ The MIT License (MIT)
9
+
10
+ Copyright (c) 2015 Sebastiaan Boer
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,85 @@
1
- # Temporary Holding Version
1
+ # workclock
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Business-time arithmetic for JavaScript and TypeScript: working hours, breaks,
4
+ holidays and IANA time zones, compiled from Rust to WebAssembly.
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ npm install workclock
10
+ ```
11
+
12
+ It runs on Node.js 22 or later, in bundlers and in browsers, and ships its
13
+ TypeScript types.
14
+
15
+ ## Quickstart
16
+
17
+ A London support desk works 09:00–17:00 with a lunch break, and is closed on
18
+ Christmas Day and the substitute Boxing Day holiday. A ticket opened at 16:30
19
+ on Christmas Eve with an 8-hour SLA:
20
+
21
+ ```js
22
+ import { Schedule } from "workclock";
23
+
24
+ const support = new Schedule({
25
+ timeZone: "Europe/London",
26
+ rules: [
27
+ { type: "workday", start: "09:00", end: "17:00" },
28
+ { type: "break", start: "12:00", end: "13:00" },
29
+ { type: "holidays", dates: ["2026-12-25", "2026-12-28"] },
30
+ ],
31
+ });
32
+
33
+ support.add("2026-12-24T16:30:00Z", 8 * 3_600_000); // Date 2026-12-30T09:30:00.000Z
34
+ support.between("2026-12-24T16:30:00Z", new Date("2026-12-29T11:00:00Z")); // 9000000 ms
35
+ support.nextPeriod("2026-12-29T11:00:00Z").end; // Date 2026-12-29T12:00:00.000Z
36
+ ```
37
+
38
+ `sub` counts back, and `previousPeriod` finds the period of working time at or
39
+ before an instant. Rules are `"workday"`, `"break"` or `"holidays"`; times are
40
+ `HH:MM[:SS[.fff]]`, `days` defaults to Monday to Friday, and each rule can set
41
+ its own `timeZone`.
42
+
43
+ ## Instants and durations
44
+
45
+ - Instants are `Date`s or ISO 8601 strings with a UTC offset, such as
46
+ `"2026-01-05T09:00:00Z"` or `"2026-01-05T10:00:00+01:00"`. A string without
47
+ an offset is rejected.
48
+ - Durations are whole numbers of milliseconds, negative to go back in time.
49
+ Any other type throws `TypeError`; it is not converted.
50
+ - Results are `Date`s and numbers, exact to the millisecond.
51
+ - The supported range is -009999-01-02T01:59:59Z to 9999-12-30T22:00:00Z.
52
+
53
+ `betweenMany`, `addMany` and `subMany` take arrays of instants, or a
54
+ `Float64Array` of epoch milliseconds for the fastest path, and process them in
55
+ one call.
56
+
57
+ ## Errors
58
+
59
+ Schedule errors are instances of `WorkclockError`, with a `kind`:
60
+
61
+ | Class | `kind` | Thrown when |
62
+ |---|---|---|
63
+ | `NoWorkingTimeError` | `"no_working_time"` | The rules have no working time, or a search finds none within 366 days, plus seven days per holiday date. |
64
+ | `OutOfRangeError` | `"out_of_range"` | An instant or a result is outside the supported range. |
65
+ | `UnknownZoneError` | `"unknown_zone"` | A time zone is not in the IANA database. |
66
+
67
+ `WorkclockError` itself has the kind `"unknown"`. Malformed input, such as a
68
+ rule without `start` or a string without an offset, throws a built-in
69
+ `TypeError` or `RangeError` instead.
70
+
71
+ ## Browsers without a bundler
72
+
73
+ Import from `workclock/web`, and call its default export once before using
74
+ anything else: `await init()` fetches `workclock_bg.wasm` from the package's
75
+ `pkg/web/` directory, so serve that directory with your page. With a bundler,
76
+ or in Node.js, import from `workclock` as above.
77
+
78
+ ## Links
79
+
80
+ - [Repository](https://github.com/Karthik-beta/workclock)
81
+ - [Specification and examples](https://github.com/Karthik-beta/workclock/blob/main/DESIGN.md)
82
+ - [JavaScript examples](https://github.com/Karthik-beta/workclock/tree/main/js/examples)
83
+ - [Changelog](https://github.com/Karthik-beta/workclock/blob/main/CHANGELOG.md)
84
+
85
+ MIT licensed.
package/bundler.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./pkg/bundler/workclock.js";
2
+ export * from "./errors.js";
package/bundler.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./pkg/bundler/workclock.js";
2
+ export * from "./errors.js";
package/errors.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Base class of the errors a schedule throws; check with `instanceof`.
3
+ *
4
+ * Malformed input, such as a rule without `start` or an instant string
5
+ * without a UTC offset, throws a built-in `TypeError` or `RangeError`
6
+ * instead, which is not a `WorkclockError`.
7
+ */
8
+ export declare class WorkclockError extends Error {
9
+ /**
10
+ * `"no_working_time"`, `"out_of_range"` or `"unknown_zone"` for the
11
+ * subclasses below, or `"unknown"` for an error this version does not
12
+ * classify further.
13
+ */
14
+ readonly kind: string;
15
+ }
16
+
17
+ /**
18
+ * The rules have no working time, or a search found none within 366 days,
19
+ * plus seven days per holiday date.
20
+ */
21
+ export declare class NoWorkingTimeError extends WorkclockError {
22
+ readonly kind: "no_working_time";
23
+ }
24
+
25
+ /**
26
+ * An instant falls outside the supported range, -009999-01-02T01:59:59Z to
27
+ * 9999-12-30T22:00:00Z.
28
+ */
29
+ export declare class OutOfRangeError extends WorkclockError {
30
+ readonly kind: "out_of_range";
31
+ }
32
+
33
+ /** A time zone name is not in the IANA database. */
34
+ export declare class UnknownZoneError extends WorkclockError {
35
+ readonly kind: "unknown_zone";
36
+ }
package/errors.js ADDED
@@ -0,0 +1,46 @@
1
+ // The WebAssembly module throws plain `Error` objects carrying a `kind`, so
2
+ // besides the usual prototype check these classes recognise errors by `kind`.
3
+ // That also keeps `instanceof` working across the node, bundler and web builds.
4
+
5
+ function isInstance(Class, value, kinds) {
6
+ return (
7
+ Function.prototype[Symbol.hasInstance].call(Class, value) ||
8
+ (value instanceof Error && kinds.includes(value.kind))
9
+ );
10
+ }
11
+
12
+ export class WorkclockError extends Error {
13
+ name = "WorkclockError";
14
+ kind = "unknown";
15
+
16
+ static [Symbol.hasInstance](value) {
17
+ return isInstance(this, value, ["no_working_time", "out_of_range", "unknown_zone", "unknown"]);
18
+ }
19
+ }
20
+
21
+ export class NoWorkingTimeError extends WorkclockError {
22
+ name = "NoWorkingTimeError";
23
+ kind = "no_working_time";
24
+
25
+ static [Symbol.hasInstance](value) {
26
+ return isInstance(this, value, ["no_working_time"]);
27
+ }
28
+ }
29
+
30
+ export class OutOfRangeError extends WorkclockError {
31
+ name = "OutOfRangeError";
32
+ kind = "out_of_range";
33
+
34
+ static [Symbol.hasInstance](value) {
35
+ return isInstance(this, value, ["out_of_range"]);
36
+ }
37
+ }
38
+
39
+ export class UnknownZoneError extends WorkclockError {
40
+ name = "UnknownZoneError";
41
+ kind = "unknown_zone";
42
+
43
+ static [Symbol.hasInstance](value) {
44
+ return isInstance(this, value, ["unknown_zone"]);
45
+ }
46
+ }
package/node.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./pkg/node/workclock.js";
2
+ export * from "./errors.js";
package/node.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./pkg/node/workclock.js";
2
+ export * from "./errors.js";
package/package.json CHANGED
@@ -1,6 +1,88 @@
1
1
  {
2
2
  "name": "workclock",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Fast, correct business-time arithmetic: working hours, SLAs and shifts",
5
+ "keywords": [
6
+ "business-hours",
7
+ "working-hours",
8
+ "sla",
9
+ "timezone",
10
+ "shift",
11
+ "business-time"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "Karthik P",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/Karthik-beta/workclock.git",
18
+ "directory": "js"
19
+ },
20
+ "homepage": "https://github.com/Karthik-beta/workclock#readme",
21
+ "bugs": "https://github.com/Karthik-beta/workclock/issues",
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "node": {
26
+ "types": "./node.d.ts",
27
+ "default": "./node.js"
28
+ },
29
+ "browser": {
30
+ "types": "./bundler.d.ts",
31
+ "default": "./bundler.js"
32
+ },
33
+ "default": {
34
+ "types": "./bundler.d.ts",
35
+ "default": "./bundler.js"
36
+ }
37
+ },
38
+ "./web": {
39
+ "types": "./web.d.ts",
40
+ "default": "./web.js"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "types": "./node.d.ts",
45
+ "files": [
46
+ "node.js",
47
+ "node.d.ts",
48
+ "bundler.js",
49
+ "bundler.d.ts",
50
+ "web.js",
51
+ "web.d.ts",
52
+ "errors.js",
53
+ "errors.d.ts",
54
+ "pkg/*/package.json",
55
+ "pkg/*/workclock.js",
56
+ "pkg/*/workclock.d.ts",
57
+ "pkg/*/workclock_bg.js",
58
+ "pkg/*/workclock_bg.wasm",
59
+ "pkg/*/workclock_bg.wasm.d.ts",
60
+ "README.md",
61
+ "LICENSE",
62
+ "NOTICE"
63
+ ],
64
+ "sideEffects": [
65
+ "./pkg/bundler/workclock.js"
66
+ ],
67
+ "engines": {
68
+ "node": ">=22"
69
+ },
70
+ "scripts": {
71
+ "build": "npm run build:node && npm run build:bundler && npm run build:web && npm run build:unignore",
72
+ "build:node": "wasm-pack build ../crates/workclock-wasm --release --target nodejs --out-dir ../../js/pkg/node --out-name workclock",
73
+ "build:bundler": "wasm-pack build ../crates/workclock-wasm --release --target bundler --out-dir ../../js/pkg/bundler --out-name workclock",
74
+ "build:web": "wasm-pack build ../crates/workclock-wasm --release --target web --out-dir ../../js/pkg/web --out-name workclock",
75
+ "build:unignore": "node --eval \"for (const t of ['node', 'bundler', 'web']) require('node:fs').rmSync('pkg/' + t + '/.gitignore', { force: true })\"",
76
+ "prepack": "node --eval \"for (const f of ['LICENSE', 'NOTICE']) require('node:fs').copyFileSync('../' + f, f)\"",
77
+ "typecheck": "tsc --noEmit",
78
+ "test": "vitest run",
79
+ "bench": "node bench/bench.js"
80
+ },
81
+ "devDependencies": {
82
+ "@types/node": "^22.20.5",
83
+ "fast-check": "^4.10.2",
84
+ "tinybench": "^6.2.2",
85
+ "typescript": "^7.0.2",
86
+ "vitest": "^5.0.5"
87
+ }
88
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "workclock-wasm",
3
+ "type": "module",
4
+ "version": "0.1.1",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Karthik-beta/workclock"
9
+ },
10
+ "files": [
11
+ "workclock_bg.wasm",
12
+ "workclock.js",
13
+ "workclock_bg.js",
14
+ "workclock.d.ts"
15
+ ],
16
+ "main": "workclock.js",
17
+ "types": "workclock.d.ts",
18
+ "sideEffects": [
19
+ "./workclock.js",
20
+ "./snippets/*"
21
+ ]
22
+ }
@@ -0,0 +1,209 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /** A day of the week. */
5
+ export type Weekday = "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun";
6
+
7
+ /**
8
+ * Working hours (`"workday"`) or time off within them (`"break"`) on some days
9
+ * of the week. Times are wall-clock times in the rule's time zone, written
10
+ * `HH:MM`, `HH:MM:SS` or `HH:MM:SS.fff` on a 24-hour clock, such as `"09:00"`
11
+ * or `"17:30:00"`.
12
+ */
13
+ export interface HoursRule {
14
+ type: "workday" | "break";
15
+ /** Wall-clock start, such as `"09:00"`. */
16
+ start: string;
17
+ /** Wall-clock end; at or before `start` means the hours end the next day. */
18
+ end: string;
19
+ /**
20
+ * Days on which the hours start. Defaults to Monday to Friday, for breaks
21
+ * too, so a break on a weekend workday needs its own `days`.
22
+ */
23
+ days?: readonly Weekday[];
24
+ /** IANA time zone; defaults to the schedule's. */
25
+ timeZone?: string;
26
+ }
27
+
28
+ /** Dates that are not worked, each from 00:00 to the next 00:00. */
29
+ export interface HolidaysRule {
30
+ type: "holidays";
31
+ /** Dates such as `"2026-12-25"`. */
32
+ dates: readonly string[];
33
+ /** IANA time zone; defaults to the schedule's. */
34
+ timeZone?: string;
35
+ }
36
+
37
+ /**
38
+ * One rule of a schedule. Working time is the time inside workdays and
39
+ * outside breaks and holidays.
40
+ */
41
+ export type Rule = HoursRule | HolidaysRule;
42
+
43
+ /** What `new Schedule` takes. */
44
+ export interface ScheduleOptions {
45
+ /** IANA time zone for rules without their own; defaults to `"UTC"`. */
46
+ timeZone?: string;
47
+ /** The rules, in any order. */
48
+ rules: readonly Rule[];
49
+ }
50
+
51
+ /** A `Date`, or an ISO 8601 string with a UTC offset. */
52
+ export type Instant = Date | string;
53
+
54
+ /** A period: a maximal stretch of working time. */
55
+ export interface Period {
56
+ start: Date;
57
+ end: Date;
58
+ }
59
+
60
+ /**
61
+ * Batch methods. Instants come as an array of `Instant`s, returning numbers or
62
+ * `Date`s, or as a `Float64Array` of milliseconds since the epoch, returning a
63
+ * `Float64Array`. Durations come as one number for every item, or one per item.
64
+ * A failing item throws, naming its index.
65
+ */
66
+ export interface Schedule {
67
+ /**
68
+ * `between` for each pair.
69
+ * @throws {RangeError} If `a` and `b` differ in length.
70
+ */
71
+ betweenMany(a: Float64Array, b: Float64Array): Float64Array;
72
+ betweenMany(a: readonly Instant[], b: readonly Instant[]): number[];
73
+ betweenMany(a: Float64Array | readonly Instant[], b: Float64Array | readonly Instant[]): Float64Array | number[];
74
+ /** `add` for each instant. */
75
+ addMany(t: Float64Array, ms: number | readonly number[] | Float64Array): Float64Array;
76
+ addMany(t: readonly Instant[], ms: number | readonly number[] | Float64Array): Date[];
77
+ addMany(t: Float64Array | readonly Instant[], ms: number | readonly number[] | Float64Array): Float64Array | Date[];
78
+ /** `sub` for each instant. */
79
+ subMany(t: Float64Array, ms: number | readonly number[] | Float64Array): Float64Array;
80
+ subMany(t: readonly Instant[], ms: number | readonly number[] | Float64Array): Date[];
81
+ subMany(t: Float64Array | readonly Instant[], ms: number | readonly number[] | Float64Array): Float64Array | Date[];
82
+ }
83
+
84
+
85
+
86
+ /**
87
+ * Working time defined by rules, evaluated in IANA time zones.
88
+ *
89
+ * Instants are `Date`s or ISO 8601 strings with a UTC offset, and durations
90
+ * are numbers of milliseconds. Results are exact to the millisecond.
91
+ */
92
+ export class Schedule {
93
+ free(): void;
94
+ [Symbol.dispose](): void;
95
+ /**
96
+ * Finds the instant a given amount of working time after another.
97
+ *
98
+ * @param t The instant to count from.
99
+ * @param ms Working time in milliseconds; a negative amount counts back.
100
+ * @returns The earliest instant with `ms` of working time after `t`, or
101
+ * `t` itself when `ms` is zero.
102
+ * @throws {NoWorkingTimeError} If no working time is found within 366
103
+ * days, plus seven days per holiday date.
104
+ * @throws {OutOfRangeError} If `t` or the result is outside the supported
105
+ * range.
106
+ * @throws {TypeError} If `t` is neither a `Date` nor a string, or `ms` is
107
+ * not a number.
108
+ * @throws {RangeError} If `t` is malformed, or `ms` is not a whole number
109
+ * within ±`Number.MAX_SAFE_INTEGER`.
110
+ * @example
111
+ * ```js
112
+ * const due = support.add("2026-12-24T16:30:00Z", 8 * 3_600_000);
113
+ * due.toISOString(); // "2026-12-30T09:30:00.000Z"
114
+ * ```
115
+ */
116
+ add(t: Instant, ms: number): Date;
117
+ /**
118
+ * Measures the working time between two instants.
119
+ *
120
+ * @param a The start.
121
+ * @param b The end.
122
+ * @returns The working time in milliseconds; negative when `b` is before
123
+ * `a`.
124
+ * @throws {OutOfRangeError} If an instant is outside the supported range.
125
+ * @throws {TypeError} If an instant is neither a `Date` nor a string.
126
+ * @throws {RangeError} If an instant is an invalid `Date` or a string
127
+ * without a UTC offset.
128
+ * @example
129
+ * ```js
130
+ * support.between("2026-01-05T09:00:00Z", "2026-01-06T09:00:00Z"); // 25200000, 7 hours
131
+ * ```
132
+ */
133
+ between(a: Instant, b: Instant): number;
134
+ /**
135
+ * Builds a schedule from its rules.
136
+ *
137
+ * @param options The default time zone and the rules.
138
+ * @throws {UnknownZoneError} If a time zone is not in the IANA database.
139
+ * @throws {NoWorkingTimeError} If the working hours minus the breaks are
140
+ * empty.
141
+ * @throws {TypeError} If `options` or a rule has the wrong shape; the
142
+ * message names the rule, such as `rules[1]`.
143
+ * @throws {RangeError} If a time, day or date cannot be read.
144
+ * @example
145
+ * ```js
146
+ * const support = new Schedule({
147
+ * timeZone: "Europe/London",
148
+ * rules: [
149
+ * { type: "workday", start: "09:00", end: "17:00" },
150
+ * { type: "break", start: "12:00", end: "13:00" },
151
+ * { type: "holidays", dates: ["2026-12-25", "2026-12-28"] },
152
+ * ],
153
+ * });
154
+ * ```
155
+ */
156
+ constructor(options: ScheduleOptions);
157
+ /**
158
+ * Finds the period of working time at or after an instant.
159
+ *
160
+ * @param t The instant to search from.
161
+ * @returns The period that contains `t`, starting at `t`, or else the
162
+ * first one after it.
163
+ * @throws {NoWorkingTimeError} If no working time is found within 366
164
+ * days, plus seven days per holiday date.
165
+ * @throws {OutOfRangeError} If `t` is outside the supported range, or the
166
+ * search reaches its end.
167
+ * @throws {TypeError} If `t` is neither a `Date` nor a string.
168
+ * @throws {RangeError} If `t` is malformed.
169
+ */
170
+ nextPeriod(t: Instant): Period;
171
+ /**
172
+ * Finds the period of working time at or before an instant.
173
+ *
174
+ * @param t The instant to search back from.
175
+ * @returns The period that contains `t`, ending at `t`, or else the last
176
+ * one before it.
177
+ * @throws {NoWorkingTimeError} If no working time is found within 366
178
+ * days, plus seven days per holiday date.
179
+ * @throws {OutOfRangeError} If `t` is outside the supported range, or the
180
+ * search reaches its start.
181
+ * @throws {TypeError} If `t` is neither a `Date` nor a string.
182
+ * @throws {RangeError} If `t` is malformed.
183
+ */
184
+ previousPeriod(t: Instant): Period;
185
+ /**
186
+ * Finds the instant a given amount of working time before another.
187
+ *
188
+ * @param t The instant to count back from.
189
+ * @param ms Working time in milliseconds; a negative amount counts
190
+ * forward.
191
+ * @returns The latest instant with `ms` of working time before `t`, or
192
+ * `t` itself when `ms` is zero.
193
+ * @throws {NoWorkingTimeError} If no working time is found within 366
194
+ * days, plus seven days per holiday date.
195
+ * @throws {OutOfRangeError} If `t` or the result is outside the supported
196
+ * range.
197
+ * @throws {TypeError} If `t` is neither a `Date` nor a string, or `ms` is
198
+ * not a number.
199
+ * @throws {RangeError} If `t` is malformed, or `ms` is not a whole number
200
+ * within ±`Number.MAX_SAFE_INTEGER`.
201
+ */
202
+ sub(t: Instant, ms: number): Date;
203
+ }
204
+
205
+ /**
206
+ * Returns the version of workclock this module was built from, such as
207
+ * `"0.1.0"`.
208
+ */
209
+ export function version(): string;
@@ -0,0 +1,9 @@
1
+ /* @ts-self-types="./workclock.d.ts" */
2
+ import * as wasm from "./workclock_bg.wasm";
3
+ import { __wbg_set_wasm } from "./workclock_bg.js";
4
+
5
+ __wbg_set_wasm(wasm);
6
+ wasm.__wbindgen_start();
7
+ export {
8
+ Schedule, version
9
+ } from "./workclock_bg.js";