@livestore/livestore 0.3.0-dev.19 → 0.3.0-dev.21

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 (83) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/SqliteDbWrapper.d.ts.map +1 -1
  3. package/dist/SqliteDbWrapper.js +1 -2
  4. package/dist/SqliteDbWrapper.js.map +1 -1
  5. package/dist/effect/LiveStore.d.ts +6 -38
  6. package/dist/effect/LiveStore.d.ts.map +1 -1
  7. package/dist/effect/LiveStore.js +6 -18
  8. package/dist/effect/LiveStore.js.map +1 -1
  9. package/dist/effect/mod.d.ts +3 -0
  10. package/dist/effect/mod.d.ts.map +1 -0
  11. package/dist/effect/mod.js +3 -0
  12. package/dist/effect/mod.js.map +1 -0
  13. package/dist/internal/mod.d.ts +3 -0
  14. package/dist/internal/mod.d.ts.map +1 -0
  15. package/dist/internal/mod.js +3 -0
  16. package/dist/internal/mod.js.map +1 -0
  17. package/dist/live-queries/base-class.d.ts +10 -6
  18. package/dist/live-queries/base-class.d.ts.map +1 -1
  19. package/dist/live-queries/base-class.js.map +1 -1
  20. package/dist/live-queries/computed.d.ts.map +1 -1
  21. package/dist/live-queries/computed.js +1 -1
  22. package/dist/live-queries/computed.js.map +1 -1
  23. package/dist/live-queries/db-query.d.ts.map +1 -1
  24. package/dist/live-queries/db-query.js +1 -2
  25. package/dist/live-queries/db-query.js.map +1 -1
  26. package/dist/live-queries/db-query.test.js +4 -1
  27. package/dist/live-queries/db-query.test.js.map +1 -1
  28. package/dist/live-queries/mod.d.ts +5 -0
  29. package/dist/live-queries/mod.d.ts.map +1 -0
  30. package/dist/live-queries/mod.js +5 -0
  31. package/dist/live-queries/mod.js.map +1 -0
  32. package/dist/{index.d.ts → mod.d.ts} +3 -8
  33. package/dist/mod.d.ts.map +1 -0
  34. package/dist/{index.js → mod.js} +2 -6
  35. package/dist/mod.js.map +1 -0
  36. package/dist/store/create-store.d.ts +42 -9
  37. package/dist/store/create-store.d.ts.map +1 -1
  38. package/dist/store/create-store.js +14 -5
  39. package/dist/store/create-store.js.map +1 -1
  40. package/dist/store/devtools.d.ts.map +1 -1
  41. package/dist/store/devtools.js +40 -15
  42. package/dist/store/devtools.js.map +1 -1
  43. package/dist/store/store-types.d.ts +4 -14
  44. package/dist/store/store-types.d.ts.map +1 -1
  45. package/dist/store/store.d.ts +4 -6
  46. package/dist/store/store.d.ts.map +1 -1
  47. package/dist/store/store.js +5 -9
  48. package/dist/store/store.js.map +1 -1
  49. package/dist/utils/tests/fixture.d.ts +1 -1
  50. package/dist/utils/tests/fixture.d.ts.map +1 -1
  51. package/dist/utils/tests/fixture.js.map +1 -1
  52. package/package.json +20 -22
  53. package/src/SqliteDbWrapper.ts +8 -2
  54. package/src/effect/LiveStore.ts +22 -70
  55. package/src/effect/{index.ts → mod.ts} +2 -3
  56. package/src/internal/mod.ts +2 -0
  57. package/src/live-queries/base-class.ts +12 -7
  58. package/src/live-queries/computed.ts +1 -1
  59. package/src/live-queries/db-query.test.ts +4 -1
  60. package/src/live-queries/db-query.ts +1 -1
  61. package/src/live-queries/mod.ts +4 -0
  62. package/src/{index.ts → mod.ts} +3 -35
  63. package/src/store/create-store.ts +66 -21
  64. package/src/store/devtools.ts +43 -15
  65. package/src/store/store-types.ts +4 -20
  66. package/src/store/store.ts +10 -24
  67. package/src/utils/tests/fixture.ts +1 -1
  68. package/dist/effect/index.d.ts +0 -2
  69. package/dist/effect/index.d.ts.map +0 -1
  70. package/dist/effect/index.js +0 -2
  71. package/dist/effect/index.js.map +0 -1
  72. package/dist/index.d.ts.map +0 -1
  73. package/dist/index.js.map +0 -1
  74. package/dist/live-queries/graphql.d.ts +0 -49
  75. package/dist/live-queries/graphql.d.ts.map +0 -1
  76. package/dist/live-queries/graphql.js +0 -147
  77. package/dist/live-queries/graphql.js.map +0 -1
  78. package/dist/utils/otel.d.ts +0 -4
  79. package/dist/utils/otel.d.ts.map +0 -1
  80. package/dist/utils/otel.js +0 -6
  81. package/dist/utils/otel.js.map +0 -1
  82. package/src/live-queries/graphql.ts +0 -244
  83. package/src/utils/otel.ts +0 -9
@@ -1,147 +0,0 @@
1
- import { shouldNeverHappen } from '@livestore/utils';
2
- import { Schema, TreeFormatter } from '@livestore/utils/effect';
3
- import * as otel from '@opentelemetry/api';
4
- import * as graphql from 'graphql';
5
- import { isThunk } from '../reactive.js';
6
- import { getDurationMsFromSpan } from '../utils/otel.js';
7
- import { depsToString, LiveStoreQueryBase, makeGetAtomResult, withRCMap } from './base-class.js';
8
- export const queryGraphQL = (document, genVariableValues, options = {}) => {
9
- const documentName = graphql.getOperationAST(document)?.name?.value;
10
- const hash = options.deps
11
- ? depsToString(options.deps)
12
- : (documentName ?? shouldNeverHappen('No document name found and no deps provided'));
13
- const label = options.label ?? documentName ?? 'graphql';
14
- const map = options.map;
15
- return {
16
- _tag: 'def',
17
- make: withRCMap(hash, (ctx, _otelContext) => {
18
- return new LiveStoreGraphQLQuery({
19
- document,
20
- genVariableValues,
21
- label,
22
- map,
23
- reactivityGraph: ctx.reactivityGraph.deref(),
24
- });
25
- }),
26
- label,
27
- hash,
28
- queryInfo: { _tag: 'None' },
29
- };
30
- };
31
- export class LiveStoreGraphQLQuery extends LiveStoreQueryBase {
32
- _tag = 'graphql';
33
- /** The abstract GraphQL query */
34
- document;
35
- /** A reactive thunk representing the query results */
36
- results$;
37
- variableValues$;
38
- label;
39
- reactivityGraph;
40
- queryInfo = { _tag: 'None' };
41
- mapResult;
42
- constructor({ document, label, genVariableValues, reactivityGraph, map, }) {
43
- super();
44
- const labelWithDefault = label ?? graphql.getOperationAST(document)?.name?.value ?? 'graphql';
45
- this.label = labelWithDefault;
46
- this.document = document;
47
- this.reactivityGraph = reactivityGraph;
48
- this.mapResult =
49
- map === undefined
50
- ? (res) => res
51
- : Schema.isSchema(map)
52
- ? (res) => {
53
- const parseResult = Schema.decodeEither(map)(res);
54
- if (parseResult._tag === 'Left') {
55
- console.error(`Error parsing GraphQL query result: ${TreeFormatter.formatErrorSync(parseResult.left)}`);
56
- return shouldNeverHappen(`Error parsing SQL query result: ${parseResult.left}`);
57
- }
58
- else {
59
- return parseResult.right;
60
- }
61
- }
62
- : typeof map === 'function'
63
- ? map
64
- : shouldNeverHappen(`Invalid map function ${map}`);
65
- // TODO don't even create a thunk if variables are static
66
- let variableValues$OrvariableValues;
67
- if (typeof genVariableValues === 'function') {
68
- variableValues$OrvariableValues = this.reactivityGraph.makeThunk((get, _setDebugInfo, ctx, otelContext) => {
69
- return genVariableValues(makeGetAtomResult(get, ctx, otelContext ?? ctx.rootOtelContext, this.dependencyQueriesRef));
70
- }, { label: `${labelWithDefault}:variableValues`, meta: { liveStoreThunkType: 'graphql.variables' } });
71
- this.variableValues$ = variableValues$OrvariableValues;
72
- }
73
- else {
74
- variableValues$OrvariableValues = genVariableValues;
75
- }
76
- const resultsLabel = `${labelWithDefault}:results`;
77
- this.results$ = this.reactivityGraph.makeThunk((get, setDebugInfo, ctx, otelContext, debugRefreshReason) => {
78
- const { store, otelTracer, rootOtelContext } = ctx;
79
- const variableValues = isThunk(variableValues$OrvariableValues)
80
- ? get(variableValues$OrvariableValues, otelContext, debugRefreshReason)
81
- : variableValues$OrvariableValues;
82
- const { result, queriedTables, durationMs } = this.queryOnce({
83
- document,
84
- variableValues,
85
- otelContext: otelContext ?? rootOtelContext,
86
- otelTracer,
87
- store: store,
88
- get: makeGetAtomResult(get, ctx, otelContext ?? rootOtelContext, this.dependencyQueriesRef),
89
- });
90
- // Add dependencies on any tables that were used
91
- for (const tableName of queriedTables) {
92
- const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`);
93
- get(tableRef);
94
- }
95
- setDebugInfo({ _tag: 'graphql', label: resultsLabel, query: graphql.print(document), durationMs });
96
- return result;
97
- }, { label: resultsLabel, meta: { liveStoreThunkType: 'graphql.result' } });
98
- }
99
- queryOnce = ({ document, otelContext, otelTracer, variableValues, store, get, }) => {
100
- const schema = store.graphQLSchema ?? shouldNeverHappen("Can't run a GraphQL query on a store without GraphQL schema");
101
- const context = store.graphQLContext ?? shouldNeverHappen("Can't run a GraphQL query on a store without GraphQL context");
102
- const operationName = graphql.getOperationAST(document)?.name?.value;
103
- return otelTracer.startActiveSpan(`executeGraphQLQuery: ${operationName}`, {}, otelContext, (span) => {
104
- span.setAttribute('graphql.variables', JSON.stringify(variableValues));
105
- span.setAttribute('graphql.query', graphql.print(document));
106
- context.queriedTables.clear();
107
- context.otelContext = otel.trace.setSpan(otel.context.active(), span);
108
- const res = graphql.executeSync({
109
- document,
110
- contextValue: context,
111
- schema: schema,
112
- variableValues,
113
- });
114
- // TODO track number of nested SQL queries via Otel + debug info
115
- if (res.errors) {
116
- span.setStatus({ code: otel.SpanStatusCode.ERROR, message: 'GraphQL error' });
117
- span.setAttribute('graphql.error', res.errors.join('\n'));
118
- span.setAttribute('graphql.error-detail', JSON.stringify(res.errors));
119
- console.error(`graphql error (${operationName}) - ${res.errors.length} errors`);
120
- for (const error of res.errors) {
121
- console.error(error);
122
- }
123
- debugger;
124
- shouldNeverHappen(`GraphQL error: ${res.errors.join('\n')}`);
125
- }
126
- span.end();
127
- const result = this.mapResult(res.data, get);
128
- const durationMs = getDurationMsFromSpan(span);
129
- this.executionTimes.push(durationMs);
130
- return {
131
- result,
132
- queriedTables: Array.from(context.queriedTables.values()),
133
- durationMs,
134
- };
135
- });
136
- };
137
- destroy = () => {
138
- if (this.variableValues$ !== undefined) {
139
- this.reactivityGraph.destroyNode(this.variableValues$);
140
- }
141
- this.reactivityGraph.destroyNode(this.results$);
142
- for (const query of this.dependencyQueriesRef) {
143
- query.deref();
144
- }
145
- };
146
- }
147
- //# sourceMappingURL=graphql.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../src/live-queries/graphql.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import type * as otel from '@opentelemetry/api';
2
- export declare const getDurationMsFromSpan: (span: otel.Span) => number;
3
- export declare const getStartTimeHighResFromSpan: (span: otel.Span) => DOMHighResTimeStamp;
4
- //# sourceMappingURL=otel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../src/utils/otel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAE/C,eAAO,MAAM,qBAAqB,GAAI,MAAM,IAAI,CAAC,IAAI,KAAG,MAGvD,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,MAAM,IAAI,CAAC,IAAI,KAAG,mBACF,CAAA"}
@@ -1,6 +0,0 @@
1
- export const getDurationMsFromSpan = (span) => {
2
- const durationHr = span._duration;
3
- return durationHr[0] * 1000 + durationHr[1] / 1_000_000;
4
- };
5
- export const getStartTimeHighResFromSpan = (span) => span._performanceStartTime;
6
- //# sourceMappingURL=otel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/utils/otel.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAe,EAAU,EAAE;IAC/D,MAAM,UAAU,GAAsC,IAAY,CAAC,SAAS,CAAA;IAC5E,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;AACzD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAe,EAAuB,EAAE,CACjF,IAAY,CAAC,qBAA4C,CAAA"}
@@ -1,244 +0,0 @@
1
- import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'
2
- import type { QueryInfo } from '@livestore/common'
3
- import { shouldNeverHappen } from '@livestore/utils'
4
- import { Schema, TreeFormatter } from '@livestore/utils/effect'
5
- import * as otel from '@opentelemetry/api'
6
- import * as graphql from 'graphql'
7
-
8
- import { isThunk, type Thunk } from '../reactive.js'
9
- import type { Store } from '../store/store.js'
10
- import type { BaseGraphQLContext, RefreshReason } from '../store/store-types.js'
11
- import { getDurationMsFromSpan } from '../utils/otel.js'
12
- import type { DepKey, GetAtomResult, LiveQueryDef, ReactivityGraph, ReactivityGraphContext } from './base-class.js'
13
- import { depsToString, LiveStoreQueryBase, makeGetAtomResult, withRCMap } from './base-class.js'
14
-
15
- export type MapResult<To, From> = ((res: From, get: GetAtomResult) => To) | Schema.Schema<To, From>
16
-
17
- export const queryGraphQL = <
18
- TResult extends Record<string, any>,
19
- TVariableValues extends Record<string, any>,
20
- TResultMapped extends Record<string, any> = TResult,
21
- >(
22
- document: DocumentNode<TResult, TVariableValues>,
23
- genVariableValues: TVariableValues | ((get: GetAtomResult) => TVariableValues),
24
- options: {
25
- label?: string
26
- // reactivityGraph?: ReactivityGraph
27
- map?: MapResult<TResultMapped, TResult>
28
- deps?: DepKey
29
- } = {},
30
- ): LiveQueryDef<TResultMapped, QueryInfo.None> => {
31
- const documentName = graphql.getOperationAST(document)?.name?.value
32
- const hash = options.deps
33
- ? depsToString(options.deps)
34
- : (documentName ?? shouldNeverHappen('No document name found and no deps provided'))
35
- const label = options.label ?? documentName ?? 'graphql'
36
- const map = options.map
37
-
38
- return {
39
- _tag: 'def',
40
- make: withRCMap(hash, (ctx, _otelContext) => {
41
- return new LiveStoreGraphQLQuery({
42
- document,
43
- genVariableValues,
44
- label,
45
- map,
46
- reactivityGraph: ctx.reactivityGraph.deref()!,
47
- })
48
- }),
49
- label,
50
- hash,
51
- queryInfo: { _tag: 'None' },
52
- }
53
- }
54
-
55
- export class LiveStoreGraphQLQuery<
56
- TResult extends Record<string, any>,
57
- TVariableValues extends Record<string, any>,
58
- TContext extends BaseGraphQLContext,
59
- TResultMapped extends Record<string, any> = TResult,
60
- > extends LiveStoreQueryBase<TResultMapped, QueryInfo.None> {
61
- _tag: 'graphql' = 'graphql'
62
-
63
- /** The abstract GraphQL query */
64
- document: DocumentNode<TResult, TVariableValues>
65
-
66
- /** A reactive thunk representing the query results */
67
- results$: Thunk<TResultMapped, ReactivityGraphContext, RefreshReason>
68
-
69
- variableValues$: Thunk<TVariableValues, ReactivityGraphContext, RefreshReason> | undefined
70
-
71
- label: string
72
-
73
- reactivityGraph: ReactivityGraph
74
-
75
- queryInfo: QueryInfo.None = { _tag: 'None' }
76
-
77
- private mapResult
78
-
79
- constructor({
80
- document,
81
- label,
82
- genVariableValues,
83
- reactivityGraph,
84
- map,
85
- }: {
86
- document: DocumentNode<TResult, TVariableValues>
87
- genVariableValues: TVariableValues | ((get: GetAtomResult) => TVariableValues)
88
- label?: string
89
- reactivityGraph: ReactivityGraph
90
- map?: MapResult<TResultMapped, TResult>
91
- }) {
92
- super()
93
-
94
- const labelWithDefault = label ?? graphql.getOperationAST(document)?.name?.value ?? 'graphql'
95
-
96
- this.label = labelWithDefault
97
- this.document = document
98
-
99
- this.reactivityGraph = reactivityGraph
100
-
101
- this.mapResult =
102
- map === undefined
103
- ? (res: TResult) => res as any as TResultMapped
104
- : Schema.isSchema(map)
105
- ? (res: TResult) => {
106
- const parseResult = Schema.decodeEither(map as Schema.Schema<TResultMapped, TResult>)(res)
107
- if (parseResult._tag === 'Left') {
108
- console.error(`Error parsing GraphQL query result: ${TreeFormatter.formatErrorSync(parseResult.left)}`)
109
- return shouldNeverHappen(`Error parsing SQL query result: ${parseResult.left}`)
110
- } else {
111
- return parseResult.right as TResultMapped
112
- }
113
- }
114
- : typeof map === 'function'
115
- ? map
116
- : shouldNeverHappen(`Invalid map function ${map}`)
117
-
118
- // TODO don't even create a thunk if variables are static
119
- let variableValues$OrvariableValues
120
-
121
- if (typeof genVariableValues === 'function') {
122
- variableValues$OrvariableValues = this.reactivityGraph.makeThunk(
123
- (get, _setDebugInfo, ctx, otelContext) => {
124
- return genVariableValues(
125
- makeGetAtomResult(get, ctx, otelContext ?? ctx.rootOtelContext, this.dependencyQueriesRef),
126
- )
127
- },
128
- { label: `${labelWithDefault}:variableValues`, meta: { liveStoreThunkType: 'graphql.variables' } },
129
- )
130
- this.variableValues$ = variableValues$OrvariableValues
131
- } else {
132
- variableValues$OrvariableValues = genVariableValues
133
- }
134
-
135
- const resultsLabel = `${labelWithDefault}:results`
136
- this.results$ = this.reactivityGraph.makeThunk<TResultMapped>(
137
- (get, setDebugInfo, ctx, otelContext, debugRefreshReason) => {
138
- const { store, otelTracer, rootOtelContext } = ctx
139
- const variableValues = isThunk(variableValues$OrvariableValues)
140
- ? (get(variableValues$OrvariableValues, otelContext, debugRefreshReason) as TVariableValues)
141
- : (variableValues$OrvariableValues as TVariableValues)
142
- const { result, queriedTables, durationMs } = this.queryOnce({
143
- document,
144
- variableValues,
145
- otelContext: otelContext ?? rootOtelContext,
146
- otelTracer,
147
- store: store as Store<TContext>,
148
- get: makeGetAtomResult(get, ctx, otelContext ?? rootOtelContext, this.dependencyQueriesRef),
149
- })
150
-
151
- // Add dependencies on any tables that were used
152
- for (const tableName of queriedTables) {
153
- const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`)
154
- get(tableRef)
155
- }
156
-
157
- setDebugInfo({ _tag: 'graphql', label: resultsLabel, query: graphql.print(document), durationMs })
158
-
159
- return result
160
- },
161
- { label: resultsLabel, meta: { liveStoreThunkType: 'graphql.result' } },
162
- // otelContext,
163
- )
164
- }
165
-
166
- queryOnce = ({
167
- document,
168
- otelContext,
169
- otelTracer,
170
- variableValues,
171
- store,
172
- get,
173
- }: {
174
- document: graphql.DocumentNode
175
- otelContext: otel.Context
176
- otelTracer: otel.Tracer
177
- variableValues: TVariableValues
178
- store: Store<TContext>
179
- get: GetAtomResult
180
- }) => {
181
- const schema =
182
- store.graphQLSchema ?? shouldNeverHappen("Can't run a GraphQL query on a store without GraphQL schema")
183
- const context =
184
- store.graphQLContext ?? shouldNeverHappen("Can't run a GraphQL query on a store without GraphQL context")
185
-
186
- const operationName = graphql.getOperationAST(document)?.name?.value
187
-
188
- return otelTracer.startActiveSpan(`executeGraphQLQuery: ${operationName}`, {}, otelContext, (span) => {
189
- span.setAttribute('graphql.variables', JSON.stringify(variableValues))
190
- span.setAttribute('graphql.query', graphql.print(document))
191
-
192
- context.queriedTables.clear()
193
-
194
- context.otelContext = otel.trace.setSpan(otel.context.active(), span)
195
-
196
- const res = graphql.executeSync({
197
- document,
198
- contextValue: context,
199
- schema: schema,
200
- variableValues,
201
- })
202
-
203
- // TODO track number of nested SQL queries via Otel + debug info
204
-
205
- if (res.errors) {
206
- span.setStatus({ code: otel.SpanStatusCode.ERROR, message: 'GraphQL error' })
207
- span.setAttribute('graphql.error', res.errors.join('\n'))
208
- span.setAttribute('graphql.error-detail', JSON.stringify(res.errors))
209
- console.error(`graphql error (${operationName}) - ${res.errors.length} errors`)
210
- for (const error of res.errors) {
211
- console.error(error)
212
- }
213
- debugger
214
- shouldNeverHappen(`GraphQL error: ${res.errors.join('\n')}`)
215
- }
216
-
217
- span.end()
218
-
219
- const result = this.mapResult(res.data as unknown as TResult, get)
220
-
221
- const durationMs = getDurationMsFromSpan(span)
222
-
223
- this.executionTimes.push(durationMs)
224
-
225
- return {
226
- result,
227
- queriedTables: Array.from(context.queriedTables.values()),
228
- durationMs,
229
- }
230
- })
231
- }
232
-
233
- destroy = () => {
234
- if (this.variableValues$ !== undefined) {
235
- this.reactivityGraph.destroyNode(this.variableValues$)
236
- }
237
-
238
- this.reactivityGraph.destroyNode(this.results$)
239
-
240
- for (const query of this.dependencyQueriesRef) {
241
- query.deref()
242
- }
243
- }
244
- }
package/src/utils/otel.ts DELETED
@@ -1,9 +0,0 @@
1
- import type * as otel from '@opentelemetry/api'
2
-
3
- export const getDurationMsFromSpan = (span: otel.Span): number => {
4
- const durationHr: [seconds: number, nanos: number] = (span as any)._duration
5
- return durationHr[0] * 1000 + durationHr[1] / 1_000_000
6
- }
7
-
8
- export const getStartTimeHighResFromSpan = (span: otel.Span): DOMHighResTimeStamp =>
9
- (span as any)._performanceStartTime as DOMHighResTimeStamp