@dabble/patches 0.5.22 → 0.7.0
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/README.md +221 -208
- package/dist/BaseDoc-DkP3tUhT.d.ts +206 -0
- package/dist/algorithms/client/applyCommittedChanges.d.ts +7 -0
- package/dist/algorithms/client/applyCommittedChanges.js +6 -3
- package/dist/algorithms/lww/consolidateOps.d.ts +40 -0
- package/dist/algorithms/lww/consolidateOps.js +103 -0
- package/dist/algorithms/lww/index.d.ts +2 -0
- package/dist/algorithms/lww/index.js +1 -0
- package/dist/algorithms/lww/mergeServerWithLocal.d.ts +22 -0
- package/dist/algorithms/lww/mergeServerWithLocal.js +32 -0
- package/dist/algorithms/server/commitChanges.d.ts +32 -8
- package/dist/algorithms/server/commitChanges.js +24 -10
- package/dist/algorithms/server/createVersion.d.ts +1 -1
- package/dist/algorithms/server/createVersion.js +2 -4
- package/dist/algorithms/server/getSnapshotAtRevision.d.ts +1 -1
- package/dist/algorithms/server/getStateAtRevision.d.ts +1 -1
- package/dist/algorithms/server/handleOfflineSessionsAndBatches.d.ts +1 -1
- package/dist/algorithms/server/handleOfflineSessionsAndBatches.js +5 -7
- package/dist/client/BaseDoc.d.ts +6 -0
- package/dist/client/BaseDoc.js +70 -0
- package/dist/client/ClientAlgorithm.d.ts +101 -0
- package/dist/client/ClientAlgorithm.js +0 -0
- package/dist/client/InMemoryStore.d.ts +5 -7
- package/dist/client/InMemoryStore.js +6 -35
- package/dist/client/IndexedDBStore.d.ts +39 -73
- package/dist/client/IndexedDBStore.js +17 -220
- package/dist/client/LWWAlgorithm.d.ts +43 -0
- package/dist/client/LWWAlgorithm.js +87 -0
- package/dist/client/LWWClientStore.d.ts +73 -0
- package/dist/client/LWWClientStore.js +0 -0
- package/dist/client/LWWDoc.d.ts +56 -0
- package/dist/client/LWWDoc.js +84 -0
- package/dist/client/LWWInMemoryStore.d.ts +88 -0
- package/dist/client/LWWInMemoryStore.js +208 -0
- package/dist/client/LWWIndexedDBStore.d.ts +91 -0
- package/dist/client/LWWIndexedDBStore.js +275 -0
- package/dist/client/OTAlgorithm.d.ts +42 -0
- package/dist/client/OTAlgorithm.js +113 -0
- package/dist/client/OTClientStore.d.ts +50 -0
- package/dist/client/OTClientStore.js +0 -0
- package/dist/client/OTDoc.d.ts +6 -0
- package/dist/client/OTDoc.js +97 -0
- package/dist/client/OTIndexedDBStore.d.ts +84 -0
- package/dist/client/OTIndexedDBStore.js +163 -0
- package/dist/client/Patches.d.ts +36 -16
- package/dist/client/Patches.js +60 -27
- package/dist/client/PatchesDoc.d.ts +4 -113
- package/dist/client/PatchesDoc.js +3 -153
- package/dist/client/PatchesStore.d.ts +8 -105
- package/dist/client/factories.d.ts +72 -0
- package/dist/client/factories.js +80 -0
- package/dist/client/index.d.ts +14 -5
- package/dist/client/index.js +9 -0
- package/dist/compression/index.d.ts +1 -1
- package/dist/data/change.js +4 -3
- package/dist/fractionalIndex.d.ts +67 -0
- package/dist/fractionalIndex.js +241 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.js +1 -1
- package/dist/json-patch/types.d.ts +2 -0
- package/dist/net/PatchesClient.js +15 -15
- package/dist/net/PatchesSync.d.ts +24 -12
- package/dist/net/PatchesSync.js +56 -64
- package/dist/net/index.d.ts +6 -10
- package/dist/net/index.js +6 -1
- package/dist/net/protocol/JSONRPCClient.d.ts +4 -4
- package/dist/net/protocol/JSONRPCClient.js +6 -4
- package/dist/net/protocol/JSONRPCServer.d.ts +45 -9
- package/dist/net/protocol/JSONRPCServer.js +63 -8
- package/dist/net/serverContext.d.ts +38 -0
- package/dist/net/serverContext.js +20 -0
- package/dist/net/webrtc/WebRTCTransport.js +1 -1
- package/dist/net/websocket/AuthorizationProvider.d.ts +3 -3
- package/dist/net/websocket/WebSocketServer.d.ts +29 -20
- package/dist/net/websocket/WebSocketServer.js +23 -12
- package/dist/server/BranchManager.d.ts +50 -0
- package/dist/server/BranchManager.js +0 -0
- package/dist/server/CompressedStoreBackend.d.ts +8 -6
- package/dist/server/CompressedStoreBackend.js +3 -9
- package/dist/server/LWWBranchManager.d.ts +82 -0
- package/dist/server/LWWBranchManager.js +99 -0
- package/dist/server/LWWMemoryStoreBackend.d.ts +78 -0
- package/dist/server/LWWMemoryStoreBackend.js +191 -0
- package/dist/server/LWWServer.d.ts +130 -0
- package/dist/server/LWWServer.js +207 -0
- package/dist/server/{PatchesBranchManager.d.ts → OTBranchManager.d.ts} +32 -12
- package/dist/server/{PatchesBranchManager.js → OTBranchManager.js} +26 -42
- package/dist/server/OTServer.d.ts +108 -0
- package/dist/server/OTServer.js +141 -0
- package/dist/server/PatchesHistoryManager.d.ts +20 -7
- package/dist/server/PatchesHistoryManager.js +26 -3
- package/dist/server/PatchesServer.d.ts +70 -81
- package/dist/server/PatchesServer.js +0 -176
- package/dist/server/branchUtils.d.ts +82 -0
- package/dist/server/branchUtils.js +66 -0
- package/dist/server/index.d.ts +17 -6
- package/dist/server/index.js +33 -4
- package/dist/server/tombstone.d.ts +29 -0
- package/dist/server/tombstone.js +32 -0
- package/dist/server/types.d.ts +129 -27
- package/dist/server/utils.d.ts +12 -0
- package/dist/server/utils.js +23 -0
- package/dist/solid/context.d.ts +5 -4
- package/dist/solid/doc-manager.d.ts +3 -3
- package/dist/solid/index.d.ts +5 -4
- package/dist/solid/primitives.d.ts +2 -3
- package/dist/types.d.ts +16 -14
- package/dist/vue/composables.d.ts +2 -3
- package/dist/vue/doc-manager.d.ts +3 -3
- package/dist/vue/index.d.ts +5 -4
- package/dist/vue/provider.d.ts +5 -4
- package/package.json +1 -1
- package/dist/algorithms/client/collapsePendingChanges.d.ts +0 -30
- package/dist/algorithms/client/collapsePendingChanges.js +0 -78
- package/dist/net/websocket/RPCServer.d.ts +0 -141
- package/dist/net/websocket/RPCServer.js +0 -204
- package/dist/utils/dates.d.ts +0 -43
- package/dist/utils/dates.js +0 -47
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import "../../chunk-IZ2YBCUP.js";
|
|
2
|
-
import { StatusError } from "../error.js";
|
|
3
|
-
import { JSONRPCServer } from "../protocol/JSONRPCServer.js";
|
|
4
|
-
import { denyAll } from "./AuthorizationProvider.js";
|
|
5
|
-
class RPCServer {
|
|
6
|
-
rpc;
|
|
7
|
-
auth;
|
|
8
|
-
patches;
|
|
9
|
-
history;
|
|
10
|
-
branches;
|
|
11
|
-
/**
|
|
12
|
-
* Creates a new Patches WebSocket client instance.
|
|
13
|
-
* @param patches - The patches server instance to handle document operations
|
|
14
|
-
* @param history - (Optional) History manager instance to handle versioning operations
|
|
15
|
-
* @param branches - (Optional) Branch manager instance to handle branching operations
|
|
16
|
-
* @param auth - (Optional) Authorization provider implementation. Defaults to deny-all for security.
|
|
17
|
-
*/
|
|
18
|
-
constructor({ patches, history, branches, auth = denyAll }) {
|
|
19
|
-
this.rpc = new JSONRPCServer();
|
|
20
|
-
this.patches = patches;
|
|
21
|
-
this.history = history;
|
|
22
|
-
this.branches = branches;
|
|
23
|
-
this.auth = auth;
|
|
24
|
-
this.rpc.registerMethod("getDoc", this.getDoc.bind(this));
|
|
25
|
-
this.rpc.registerMethod("getChangesSince", this.getChangesSince.bind(this));
|
|
26
|
-
this.rpc.registerMethod("commitChanges", this.commitChanges.bind(this));
|
|
27
|
-
this.rpc.registerMethod("deleteDoc", this.deleteDoc.bind(this));
|
|
28
|
-
this.rpc.registerMethod("undeleteDoc", this.undeleteDoc.bind(this));
|
|
29
|
-
if (this.history) {
|
|
30
|
-
this.rpc.registerMethod("listVersions", this.listVersions.bind(this));
|
|
31
|
-
this.rpc.registerMethod("createVersion", this.createVersion.bind(this));
|
|
32
|
-
this.rpc.registerMethod("updateVersion", this.updateVersion.bind(this));
|
|
33
|
-
this.rpc.registerMethod("getVersionState", this.getVersionState.bind(this));
|
|
34
|
-
this.rpc.registerMethod("getVersionChanges", this.getVersionChanges.bind(this));
|
|
35
|
-
this.rpc.registerMethod("listServerChanges", this.listServerChanges.bind(this));
|
|
36
|
-
}
|
|
37
|
-
if (this.branches) {
|
|
38
|
-
this.rpc.registerMethod("listBranches", this.listBranches.bind(this));
|
|
39
|
-
this.rpc.registerMethod("createBranch", this.createBranch.bind(this));
|
|
40
|
-
this.rpc.registerMethod("closeBranch", this.closeBranch.bind(this));
|
|
41
|
-
this.rpc.registerMethod("mergeBranch", this.mergeBranch.bind(this));
|
|
42
|
-
}
|
|
43
|
-
this.patches.onChangesCommitted((docId, changes, originClientId) => {
|
|
44
|
-
this.rpc.notify("changesCommitted", { docId, changes }, originClientId);
|
|
45
|
-
});
|
|
46
|
-
this.patches.onDocDeleted((docId, options, originClientId) => {
|
|
47
|
-
this.rpc.notify("docDeleted", { docId }, originClientId);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Gets the latest state (content and revision) of a document.
|
|
52
|
-
* @param connectionId - The ID of the connection making the request
|
|
53
|
-
* @param params - The document parameters
|
|
54
|
-
* @param params.docId - The ID of the document
|
|
55
|
-
* @param params.atRev - Optional revision number to get document state at
|
|
56
|
-
*/
|
|
57
|
-
async getDoc(params, ctx) {
|
|
58
|
-
const { docId, atRev } = params;
|
|
59
|
-
await this.assertRead(ctx, docId, "getDoc", params);
|
|
60
|
-
return this.patches.getDoc(docId, atRev);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Gets changes that occurred for a document after a specific revision number.
|
|
64
|
-
* @param connectionId - The ID of the connection making the request
|
|
65
|
-
* @param params - The change request parameters
|
|
66
|
-
* @param params.docId - The ID of the document
|
|
67
|
-
* @param params.rev - The revision number after which to fetch changes
|
|
68
|
-
*/
|
|
69
|
-
async getChangesSince(params, ctx) {
|
|
70
|
-
const { docId, rev } = params;
|
|
71
|
-
await this.assertRead(ctx, docId, "getChangesSince", params);
|
|
72
|
-
return this.patches.getChangesSince(docId, rev);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Applies a set of client-generated changes to a document on the server.
|
|
76
|
-
* @param connectionId - The ID of the connection making the request
|
|
77
|
-
* @param params - The change parameters
|
|
78
|
-
* @param params.docId - The ID of the document
|
|
79
|
-
* @param params.changes - An array of changes to apply
|
|
80
|
-
* @param params.options - Optional commit settings (e.g., forceCommit for migrations)
|
|
81
|
-
*/
|
|
82
|
-
async commitChanges(params, ctx) {
|
|
83
|
-
const { docId, changes, options } = params;
|
|
84
|
-
await this.assertWrite(ctx, docId, "commitChanges", params);
|
|
85
|
-
const [priorChanges, newChanges] = await this.patches.commitChanges(docId, changes, options, ctx?.clientId);
|
|
86
|
-
return [...priorChanges, ...newChanges];
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Deletes a document on the server.
|
|
90
|
-
* @param connectionId - The ID of the connection making the request
|
|
91
|
-
* @param params - The deletion parameters
|
|
92
|
-
* @param params.docId - The ID of the document to delete
|
|
93
|
-
* @param params.options - Optional deletion settings (e.g., skipTombstone)
|
|
94
|
-
*/
|
|
95
|
-
async deleteDoc(params, ctx) {
|
|
96
|
-
const { docId, options } = params;
|
|
97
|
-
await this.assertWrite(ctx, docId, "deleteDoc", params);
|
|
98
|
-
await this.patches.deleteDoc(docId, options, ctx?.clientId);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Removes the tombstone for a deleted document, allowing it to be recreated.
|
|
102
|
-
* @param params - The undelete parameters
|
|
103
|
-
* @param params.docId - The ID of the document to undelete
|
|
104
|
-
*/
|
|
105
|
-
async undeleteDoc(params, ctx) {
|
|
106
|
-
const { docId } = params;
|
|
107
|
-
await this.assertWrite(ctx, docId, "undeleteDoc", params);
|
|
108
|
-
return this.patches.undeleteDoc(docId);
|
|
109
|
-
}
|
|
110
|
-
// ---------------------------------------------------------------------------
|
|
111
|
-
// History Manager wrappers
|
|
112
|
-
// ---------------------------------------------------------------------------
|
|
113
|
-
async listVersions(params, ctx) {
|
|
114
|
-
this.assertHistoryEnabled();
|
|
115
|
-
const { docId, options } = params;
|
|
116
|
-
await this.assertRead(ctx, docId, "listVersions", params);
|
|
117
|
-
return this.history.listVersions(docId, options ?? {});
|
|
118
|
-
}
|
|
119
|
-
async createVersion(params, ctx) {
|
|
120
|
-
this.assertHistoryEnabled();
|
|
121
|
-
const { docId, metadata } = params;
|
|
122
|
-
await this.assertWrite(ctx, docId, "createVersion", params);
|
|
123
|
-
return this.history.createVersion(docId, metadata);
|
|
124
|
-
}
|
|
125
|
-
async updateVersion(params, ctx) {
|
|
126
|
-
this.assertHistoryEnabled();
|
|
127
|
-
const { docId, versionId, metadata } = params;
|
|
128
|
-
await this.assertWrite(ctx, docId, "updateVersion", params);
|
|
129
|
-
return this.history.updateVersion(docId, versionId, metadata);
|
|
130
|
-
}
|
|
131
|
-
async getVersionState(params, ctx) {
|
|
132
|
-
this.assertHistoryEnabled();
|
|
133
|
-
const { docId, versionId } = params;
|
|
134
|
-
await this.assertRead(ctx, docId, "getStateAtVersion", params);
|
|
135
|
-
return this.history.getStateAtVersion(docId, versionId);
|
|
136
|
-
}
|
|
137
|
-
async getVersionChanges(params, ctx) {
|
|
138
|
-
this.assertHistoryEnabled();
|
|
139
|
-
const { docId, versionId } = params;
|
|
140
|
-
await this.assertRead(ctx, docId, "getChangesForVersion", params);
|
|
141
|
-
return this.history.getChangesForVersion(docId, versionId);
|
|
142
|
-
}
|
|
143
|
-
async listServerChanges(params, ctx) {
|
|
144
|
-
this.assertHistoryEnabled();
|
|
145
|
-
const { docId, options } = params;
|
|
146
|
-
await this.assertRead(ctx, docId, "listServerChanges", params);
|
|
147
|
-
return this.history.listServerChanges(docId, options ?? {});
|
|
148
|
-
}
|
|
149
|
-
// ---------------------------------------------------------------------------
|
|
150
|
-
// Branch Manager wrappers
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
|
-
async listBranches(params, ctx) {
|
|
153
|
-
this.assertBranchingEnabled();
|
|
154
|
-
const { docId } = params;
|
|
155
|
-
await this.assertRead(ctx, docId, "listBranches", params);
|
|
156
|
-
return this.branches.listBranches(docId);
|
|
157
|
-
}
|
|
158
|
-
async createBranch(params, ctx) {
|
|
159
|
-
this.assertBranchingEnabled();
|
|
160
|
-
const { docId, rev, metadata } = params;
|
|
161
|
-
await this.assertWrite(ctx, docId, "createBranch", params);
|
|
162
|
-
return this.branches.createBranch(docId, rev, metadata);
|
|
163
|
-
}
|
|
164
|
-
async closeBranch(params, ctx) {
|
|
165
|
-
this.assertBranchingEnabled();
|
|
166
|
-
const { branchId } = params;
|
|
167
|
-
await this.assertWrite(ctx, branchId, "closeBranch", params);
|
|
168
|
-
return this.branches.closeBranch(branchId, "closed");
|
|
169
|
-
}
|
|
170
|
-
async mergeBranch(params, ctx) {
|
|
171
|
-
this.assertBranchingEnabled();
|
|
172
|
-
const { branchId } = params;
|
|
173
|
-
await this.assertWrite(ctx, branchId, "mergeBranch", params);
|
|
174
|
-
return this.branches.mergeBranch(branchId);
|
|
175
|
-
}
|
|
176
|
-
// ---------------------------------------------------------------------------
|
|
177
|
-
// Authorization helpers
|
|
178
|
-
// ---------------------------------------------------------------------------
|
|
179
|
-
async assertAccess(ctx, docId, kind, method, params) {
|
|
180
|
-
const ok = await this.auth.canAccess(ctx, docId, kind, method, params);
|
|
181
|
-
if (!ok) {
|
|
182
|
-
throw new StatusError(401, `${kind.toUpperCase()}_FORBIDDEN:${docId}`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
assertRead(ctx, docId, method, params) {
|
|
186
|
-
return this.assertAccess(ctx, docId, "read", method, params);
|
|
187
|
-
}
|
|
188
|
-
assertWrite(ctx, docId, method, params) {
|
|
189
|
-
return this.assertAccess(ctx, docId, "write", method, params);
|
|
190
|
-
}
|
|
191
|
-
assertHistoryEnabled() {
|
|
192
|
-
if (!this.history) {
|
|
193
|
-
throw new StatusError(404, "History is not enabled");
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
assertBranchingEnabled() {
|
|
197
|
-
if (!this.branches) {
|
|
198
|
-
throw new StatusError(404, "Branching is not enabled");
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
export {
|
|
203
|
-
RPCServer
|
|
204
|
-
};
|
package/dist/utils/dates.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Date utility functions for creating and manipulating ISO 8601 timestamps.
|
|
3
|
-
*
|
|
4
|
-
* Client-side timestamps use local timezone offsets (e.g., +04:00).
|
|
5
|
-
* Server-side timestamps use UTC with Z suffix.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Converts a Date or ISO string to UTC format without milliseconds.
|
|
9
|
-
* Example: "2025-12-26T10:00:00Z"
|
|
10
|
-
*/
|
|
11
|
-
declare function getISO(date?: Date | string): string;
|
|
12
|
-
/**
|
|
13
|
-
* Formats a Date with a specific timezone offset string.
|
|
14
|
-
* The date is adjusted to display the correct local time for that offset.
|
|
15
|
-
*/
|
|
16
|
-
declare function getLocalISO(date?: Date | string, offset?: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* Calculates milliseconds between two ISO timestamps.
|
|
19
|
-
* Returns (a - b) in milliseconds.
|
|
20
|
-
*/
|
|
21
|
-
declare function timestampDiff(a: string, b: string): number;
|
|
22
|
-
/**
|
|
23
|
-
* Clamps a timestamp to not exceed a limit, preserving the original timezone offset.
|
|
24
|
-
* Returns the original if it's <= limit, otherwise returns limit in original's timezone.
|
|
25
|
-
*
|
|
26
|
-
* Example:
|
|
27
|
-
* timestamp: "2025-12-26T18:00:00+04:00" (future)
|
|
28
|
-
* limit: "2025-12-26T10:00:00Z" (server time)
|
|
29
|
-
* result: "2025-12-26T14:00:00+04:00" (clamped, same instant as limit)
|
|
30
|
-
*/
|
|
31
|
-
declare function clampTimestamp(timestamp: string, limit: string): string;
|
|
32
|
-
/**
|
|
33
|
-
* Extracts the timezone offset string from an ISO timestamp.
|
|
34
|
-
* Returns "+04:00", "-05:00", or "Z".
|
|
35
|
-
*/
|
|
36
|
-
declare function extractTimezoneOffset(iso: string): string;
|
|
37
|
-
/**
|
|
38
|
-
* Gets the local timezone offset string for the current environment.
|
|
39
|
-
* Returns "+04:00", "-05:00", or "Z" for UTC.
|
|
40
|
-
*/
|
|
41
|
-
declare function getLocalTimezoneOffset(): string;
|
|
42
|
-
|
|
43
|
-
export { clampTimestamp, extractTimezoneOffset, getISO, getLocalISO, getLocalTimezoneOffset, timestampDiff };
|
package/dist/utils/dates.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import "../chunk-IZ2YBCUP.js";
|
|
2
|
-
function getISO(date = /* @__PURE__ */ new Date()) {
|
|
3
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
4
|
-
return d.toISOString().replace(/\.\d{3}/, "");
|
|
5
|
-
}
|
|
6
|
-
function getLocalISO(date = /* @__PURE__ */ new Date(), offset = getLocalTimezoneOffset()) {
|
|
7
|
-
const match = offset.match(/([+-])(\d{2}):(\d{2})/);
|
|
8
|
-
if (offset === "Z" || !match) return getISO(date);
|
|
9
|
-
const sign = match[1] === "+" ? 1 : -1;
|
|
10
|
-
const offsetMinutes = sign * (parseInt(match[2]) * 60 + parseInt(match[3]));
|
|
11
|
-
const localDate = new Date((typeof date === "string" ? new Date(date) : date).getTime() + offsetMinutes * 60 * 1e3);
|
|
12
|
-
return getISO(localDate).slice(0, -1) + offset;
|
|
13
|
-
}
|
|
14
|
-
function timestampDiff(a, b) {
|
|
15
|
-
return new Date(a).getTime() - new Date(b).getTime();
|
|
16
|
-
}
|
|
17
|
-
function clampTimestamp(timestamp, limit) {
|
|
18
|
-
if (!timestamp || !limit) throw new Error("Timestamp and limit are required");
|
|
19
|
-
const timestampDate = new Date(timestamp);
|
|
20
|
-
const limitDate = new Date(limit);
|
|
21
|
-
if (timestampDate <= limitDate) {
|
|
22
|
-
return timestamp;
|
|
23
|
-
}
|
|
24
|
-
const offset = extractTimezoneOffset(timestamp);
|
|
25
|
-
return getLocalISO(limitDate, offset);
|
|
26
|
-
}
|
|
27
|
-
function extractTimezoneOffset(iso) {
|
|
28
|
-
if (!iso) return "Z";
|
|
29
|
-
const match = iso.match(/([+-]\d{2}:\d{2}|Z)$/);
|
|
30
|
-
return match ? match[1] : "Z";
|
|
31
|
-
}
|
|
32
|
-
function getLocalTimezoneOffset() {
|
|
33
|
-
const offset = -(/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
34
|
-
if (offset === 0) return "Z";
|
|
35
|
-
const hours = Math.floor(Math.abs(offset) / 60);
|
|
36
|
-
const mins = Math.abs(offset) % 60;
|
|
37
|
-
const sign = offset >= 0 ? "+" : "-";
|
|
38
|
-
return `${sign}${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
|
|
39
|
-
}
|
|
40
|
-
export {
|
|
41
|
-
clampTimestamp,
|
|
42
|
-
extractTimezoneOffset,
|
|
43
|
-
getISO,
|
|
44
|
-
getLocalISO,
|
|
45
|
-
getLocalTimezoneOffset,
|
|
46
|
-
timestampDiff
|
|
47
|
-
};
|