@livestore/livestore 0.0.46 → 0.0.47
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/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/react/fixture.d.ts +10 -10
- package/dist/react/LiveStoreProvider.test.js +2 -13
- package/dist/react/LiveStoreProvider.test.js.map +1 -1
- package/dist/react/useAtom.d.ts.map +1 -1
- package/dist/react/useAtom.js +6 -1
- package/dist/react/useAtom.js.map +1 -1
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +5 -1
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/row-query.d.ts.map +1 -1
- package/dist/row-query.js +3 -1
- package/dist/row-query.js.map +1 -1
- package/dist/store.d.ts +5 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +40 -31
- package/dist/store.js.map +1 -1
- package/package.json +10 -10
- package/src/react/LiveStoreProvider.test.tsx +2 -21
- package/src/react/useAtom.ts +5 -1
- package/src/reactiveQueries/graphql.ts +5 -1
- package/src/row-query.ts +3 -1
- package/src/store.ts +59 -41
- package/dist/react/components/DiffableList copy.d.ts +0 -19
- package/dist/react/components/DiffableList copy.d.ts.map +0 -1
- package/dist/react/components/DiffableList copy.js +0 -62
- package/dist/react/components/DiffableList copy.js.map +0 -1
- package/dist/react/components/DiffableList.d.ts +0 -13
- package/dist/react/components/DiffableList.d.ts.map +0 -1
- package/dist/react/components/DiffableList.js +0 -21
- package/dist/react/components/DiffableList.js.map +0 -1
- package/dist/react/components/DiffableList2.d.ts +0 -20
- package/dist/react/components/DiffableList2.d.ts.map +0 -1
- package/dist/react/components/DiffableList2.js +0 -119
- package/dist/react/components/DiffableList2.js.map +0 -1
- package/dist/react/components/DiffableList3.d.ts +0 -19
- package/dist/react/components/DiffableList3.d.ts.map +0 -1
- package/dist/react/components/DiffableList3.js +0 -62
- package/dist/react/components/DiffableList3.js.map +0 -1
- package/dist/react/useRowOld.d.ts +0 -40
- package/dist/react/useRowOld.d.ts.map +0 -1
- package/dist/react/useRowOld.js +0 -134
- package/dist/react/useRowOld.js.map +0 -1
- package/dist/react/utils/useCleanup.d.ts +0 -7
- package/dist/react/utils/useCleanup.d.ts.map +0 -1
- package/dist/react/utils/useCleanup.js +0 -19
- package/dist/react/utils/useCleanup.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { StorageDatabase } from '@livestore/common'
|
|
2
1
|
import { sql } from '@livestore/common'
|
|
3
2
|
import { makeDb } from '@livestore/web'
|
|
3
|
+
import { InMemoryStorage } from '@livestore/web/storage/in-memory'
|
|
4
4
|
import { render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react'
|
|
5
5
|
import React from 'react'
|
|
6
6
|
import { describe, expect, it } from 'vitest'
|
|
@@ -11,25 +11,6 @@ import type { BootDb, Store } from '../store.js'
|
|
|
11
11
|
import * as LiveStoreReact from './index.js'
|
|
12
12
|
import { LiveStoreProvider } from './LiveStoreProvider.js'
|
|
13
13
|
|
|
14
|
-
class TestInMemoryStorage implements StorageDatabase {
|
|
15
|
-
filename = '__test__in-memory__'
|
|
16
|
-
|
|
17
|
-
constructor() {}
|
|
18
|
-
|
|
19
|
-
execute = async () => {}
|
|
20
|
-
|
|
21
|
-
mutate = async () => {}
|
|
22
|
-
|
|
23
|
-
export = async () => undefined
|
|
24
|
-
|
|
25
|
-
getMutationLogData = async (): Promise<Uint8Array> => new Uint8Array()
|
|
26
|
-
|
|
27
|
-
dangerouslyReset = async () => {}
|
|
28
|
-
shutdown = async () => {
|
|
29
|
-
await new Promise((resolve) => setTimeout(resolve, 200))
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
14
|
describe('LiveStoreProvider', () => {
|
|
34
15
|
it('simple', async () => {
|
|
35
16
|
let renderCount = 0
|
|
@@ -54,7 +35,7 @@ describe('LiveStoreProvider', () => {
|
|
|
54
35
|
[],
|
|
55
36
|
)
|
|
56
37
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
-
const makeDbMemo = React.useMemo(() => makeDb(() => ()
|
|
38
|
+
const makeDbMemo = React.useMemo(() => makeDb(() => InMemoryStorage.load()), [forceUpdate])
|
|
58
39
|
return (
|
|
59
40
|
<LiveStoreProvider schema={schema} fallback={<div>Loading LiveStore</div>} makeDb={makeDbMemo} boot={bootCb}>
|
|
60
41
|
<App />
|
package/src/react/useAtom.ts
CHANGED
|
@@ -17,7 +17,11 @@ export const useAtom = <TQuery extends LiveQuery<any, QueryInfoRow<any> | QueryI
|
|
|
17
17
|
return (newValueOrFn: any) => {
|
|
18
18
|
const newValue = typeof newValueOrFn === 'function' ? newValueOrFn(query$Ref.current) : newValueOrFn
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
if (query$.queryInfo._tag === 'Row' && query$.queryInfo.table.isSingleColumn) {
|
|
21
|
+
store.mutate(mutationForQueryInfo(query$.queryInfo!, { value: newValue }))
|
|
22
|
+
} else {
|
|
23
|
+
store.mutate(mutationForQueryInfo(query$.queryInfo!, newValue))
|
|
24
|
+
}
|
|
21
25
|
}
|
|
22
26
|
}, [query$.queryInfo, query$Ref, store])
|
|
23
27
|
|
|
@@ -191,7 +191,11 @@ export class LiveStoreGraphQLQuery<
|
|
|
191
191
|
span.setStatus({ code: otel.SpanStatusCode.ERROR, message: 'GraphQL error' })
|
|
192
192
|
span.setAttribute('graphql.error', res.errors.join('\n'))
|
|
193
193
|
span.setAttribute('graphql.error-detail', JSON.stringify(res.errors))
|
|
194
|
-
console.error(`graphql error (${operationName})
|
|
194
|
+
console.error(`graphql error (${operationName}) - ${res.errors.length} errors`)
|
|
195
|
+
for (const error of res.errors) {
|
|
196
|
+
console.error(error)
|
|
197
|
+
}
|
|
198
|
+
debugger
|
|
195
199
|
}
|
|
196
200
|
|
|
197
201
|
span.end()
|
package/src/row-query.ts
CHANGED
|
@@ -78,6 +78,9 @@ export const rowQuery: MakeRowQuery = <TTableDef extends DbSchema.TableDef>(
|
|
|
78
78
|
genQueryString: queryStr,
|
|
79
79
|
queriedTables: new Set([componentTableName]),
|
|
80
80
|
dbGraph: options?.dbGraph,
|
|
81
|
+
// TODO remove this once the LiveStore Devtools are no longer relying on it
|
|
82
|
+
// as the defaults rows are now already being inserted during store initialization
|
|
83
|
+
// and the tables need to be registered during initialization
|
|
81
84
|
execBeforeFirstRun: makeExecBeforeFirstRun({
|
|
82
85
|
otelContext: options?.otelContext,
|
|
83
86
|
table,
|
|
@@ -201,7 +204,6 @@ const makeExecBeforeFirstRun =
|
|
|
201
204
|
}
|
|
202
205
|
|
|
203
206
|
if (skipInsertDefaultRow !== true) {
|
|
204
|
-
// TODO find a way to only do this if necessary
|
|
205
207
|
insertRowWithDefaultValuesOrIgnore({
|
|
206
208
|
store,
|
|
207
209
|
id: id ?? 'singleton',
|
package/src/store.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
type DatabaseFactory,
|
|
3
|
+
type DatabaseImpl,
|
|
4
|
+
getExecArgsFromMutation,
|
|
5
|
+
type PreparedBindValues,
|
|
6
|
+
} from '@livestore/common'
|
|
7
|
+
import type { LiveStoreSchema, MutationEvent, MutationEventSchema } from '@livestore/common/schema'
|
|
8
|
+
import { makeMutationEventSchema } from '@livestore/common/schema'
|
|
3
9
|
import { assertNever, isPromise, makeNoopTracer, shouldNeverHappen } from '@livestore/utils'
|
|
4
10
|
import { Schema } from '@livestore/utils/effect'
|
|
5
11
|
import * as otel from '@opentelemetry/api'
|
|
@@ -7,7 +13,6 @@ import type { GraphQLSchema } from 'graphql'
|
|
|
7
13
|
|
|
8
14
|
import { globalDbGraph } from './global-state.js'
|
|
9
15
|
import { MainDatabaseWrapper } from './MainDatabaseWrapper.js'
|
|
10
|
-
import { migrateDb } from './migrations.js'
|
|
11
16
|
import type { StackInfo } from './react/utils/stack-info.js'
|
|
12
17
|
import type { DebugRefreshReasonBase, ReactiveGraph, Ref } from './reactive.js'
|
|
13
18
|
import type { DbContext, DbGraph, LiveQuery } from './reactiveQueries/base-class.js'
|
|
@@ -39,6 +44,7 @@ export type StoreOptions<
|
|
|
39
44
|
otelTracer: otel.Tracer
|
|
40
45
|
otelRootSpanContext: otel.Context
|
|
41
46
|
dbGraph: DbGraph
|
|
47
|
+
mutationEventSchema: MutationEventSchema<any>
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
export type RefreshReason =
|
|
@@ -77,6 +83,7 @@ const uniqueStoreId = () => `store-${++storeCount}`
|
|
|
77
83
|
|
|
78
84
|
export type BootDb = {
|
|
79
85
|
execute(queryStr: string, bindValues?: ParamsObject): void
|
|
86
|
+
mutate: <const TMutationArg extends ReadonlyArray<MutationEvent.Any>>(...list: TMutationArg) => void
|
|
80
87
|
select<T>(queryStr: string, bindValues?: ParamsObject): ReadonlyArray<T>
|
|
81
88
|
txn(callback: () => void): void
|
|
82
89
|
}
|
|
@@ -105,7 +112,7 @@ export class Store<
|
|
|
105
112
|
/** RC-based set to see which queries are currently subscribed to */
|
|
106
113
|
activeQueries: ReferenceCountedSet<LiveQuery<any>>
|
|
107
114
|
|
|
108
|
-
private
|
|
115
|
+
private mutationEventSchema
|
|
109
116
|
|
|
110
117
|
private constructor({
|
|
111
118
|
db,
|
|
@@ -115,6 +122,7 @@ export class Store<
|
|
|
115
122
|
dbGraph,
|
|
116
123
|
otelTracer,
|
|
117
124
|
otelRootSpanContext,
|
|
125
|
+
mutationEventSchema,
|
|
118
126
|
}: StoreOptions<TGraphQLContext, TSchema>) {
|
|
119
127
|
this.mainDbWrapper = new MainDatabaseWrapper({ otelTracer, otelRootSpanContext, db: db.mainDb })
|
|
120
128
|
this.db = db
|
|
@@ -122,7 +130,8 @@ export class Store<
|
|
|
122
130
|
this.schema = schema
|
|
123
131
|
|
|
124
132
|
// TODO refactor
|
|
125
|
-
this.
|
|
133
|
+
this.mutationEventSchema = mutationEventSchema
|
|
134
|
+
// this.mutationEventSchema = makeMutationEventSchema(Object.fromEntries(schema.mutations.entries()) as any)
|
|
126
135
|
|
|
127
136
|
// TODO generalize the `tableRefs` concept to allow finer-grained refs
|
|
128
137
|
this.tableRefs = {}
|
|
@@ -375,48 +384,43 @@ export class Store<
|
|
|
375
384
|
* the caller must refresh queries after calling this method.
|
|
376
385
|
*/
|
|
377
386
|
private mutateWithoutRefresh = (
|
|
378
|
-
|
|
387
|
+
mutationEventDecoded: MutationEvent.ForSchema<TSchema>,
|
|
379
388
|
otelContext: otel.Context,
|
|
380
389
|
): { writeTables: ReadonlySet<string>; durationMs: number } => {
|
|
381
390
|
return this.otel.tracer.startActiveSpan(
|
|
382
391
|
'LiveStore:mutatetWithoutRefresh',
|
|
383
392
|
{
|
|
384
393
|
attributes: {
|
|
385
|
-
'livestore.mutation':
|
|
386
|
-
'livestore.args': JSON.stringify(
|
|
394
|
+
'livestore.mutation': mutationEventDecoded.mutation,
|
|
395
|
+
'livestore.args': JSON.stringify(mutationEventDecoded.args, null, 2),
|
|
387
396
|
},
|
|
388
397
|
},
|
|
389
398
|
otelContext,
|
|
390
399
|
(span) => {
|
|
391
400
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
392
401
|
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
shouldNeverHappen(`Unknown mutation type: ${mutationEvent.mutation}`)
|
|
396
|
-
|
|
397
|
-
const statementRes =
|
|
398
|
-
typeof mutationDef.sql === 'function' ? mutationDef.sql(mutationEvent.args) : mutationDef.sql
|
|
402
|
+
const allWriteTables = new Set<string>()
|
|
403
|
+
let durationMsTotal = 0
|
|
399
404
|
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
? this.mainDbWrapper.getTablesUsed(statementSql)
|
|
404
|
-
: statementRes.writeTables ?? this.mainDbWrapper.getTablesUsed(statementSql)
|
|
405
|
+
const mutationDef =
|
|
406
|
+
this.schema.mutations.get(mutationEventDecoded.mutation) ??
|
|
407
|
+
shouldNeverHappen(`Unknown mutation type: ${mutationEventDecoded.mutation}`)
|
|
405
408
|
|
|
406
|
-
const
|
|
407
|
-
typeof statementRes === 'string'
|
|
408
|
-
? Schema.encodeUnknownSync(mutationDef.schema)(mutationEvent.args)
|
|
409
|
-
: statementRes.bindValues
|
|
409
|
+
const execArgsArr = getExecArgsFromMutation({ mutationDef, mutationEventDecoded })
|
|
410
410
|
|
|
411
|
-
const {
|
|
411
|
+
for (const {
|
|
412
412
|
statementSql,
|
|
413
|
-
|
|
414
|
-
writeTables,
|
|
415
|
-
|
|
416
|
-
|
|
413
|
+
bindValues,
|
|
414
|
+
writeTables = this.mainDbWrapper.getTablesUsed(statementSql),
|
|
415
|
+
} of execArgsArr) {
|
|
416
|
+
const { durationMs } = this.mainDbWrapper.execute(statementSql, bindValues, writeTables, { otelContext })
|
|
417
|
+
|
|
418
|
+
durationMsTotal += durationMs
|
|
419
|
+
writeTables.forEach((table) => allWriteTables.add(table))
|
|
420
|
+
}
|
|
417
421
|
|
|
418
422
|
// Asynchronously apply mutation to a persistent storage (we're not awaiting this promise here)
|
|
419
|
-
const mutationEventEncoded = Schema.encodeUnknownSync(this.
|
|
423
|
+
const mutationEventEncoded = Schema.encodeUnknownSync(this.mutationEventSchema)(mutationEventDecoded)
|
|
420
424
|
this.db.storageDb.mutate(mutationEventEncoded, span)
|
|
421
425
|
|
|
422
426
|
// Uncomment to print a list of queries currently registered on the store
|
|
@@ -424,7 +428,7 @@ export class Store<
|
|
|
424
428
|
|
|
425
429
|
span.end()
|
|
426
430
|
|
|
427
|
-
return { writeTables, durationMs }
|
|
431
|
+
return { writeTables: allWriteTables, durationMs: durationMsTotal }
|
|
428
432
|
},
|
|
429
433
|
)
|
|
430
434
|
}
|
|
@@ -496,24 +500,21 @@ export const createStore = async <
|
|
|
496
500
|
}): Promise<Store<TGraphQLContext, TSchema>> => {
|
|
497
501
|
return otelTracer.startActiveSpan('createStore', {}, otelRootSpanContext, async (span) => {
|
|
498
502
|
try {
|
|
503
|
+
performance.mark('livestore:db-creating')
|
|
499
504
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
500
505
|
|
|
501
|
-
const dbPromise = makeDb({ otelTracer, otelContext })
|
|
506
|
+
const dbPromise = makeDb({ otelTracer, otelContext, schema })
|
|
502
507
|
const db = dbPromise instanceof Promise ? await dbPromise : dbPromise
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
try {
|
|
506
|
-
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
507
|
-
migrateDb({ db, schema, otelContext })
|
|
508
|
-
} finally {
|
|
509
|
-
span.end()
|
|
510
|
-
}
|
|
511
|
-
})
|
|
508
|
+
performance.mark('livestore:db-created')
|
|
509
|
+
performance.measure('livestore:db-create', 'livestore:db-creating', 'livestore:db-created')
|
|
512
510
|
|
|
513
511
|
if (batchUpdates !== undefined) {
|
|
514
512
|
dbGraph.effectsWrapper = batchUpdates
|
|
515
513
|
}
|
|
516
514
|
|
|
515
|
+
const mutationEventSchema = makeMutationEventSchema(Object.fromEntries(schema.mutations.entries()) as any)
|
|
516
|
+
|
|
517
|
+
// TODO consider moving booting into the storage backend
|
|
517
518
|
if (boot !== undefined) {
|
|
518
519
|
let isInTxn = false
|
|
519
520
|
let txnExecuteStmnts: [string, PreparedBindValues | undefined][] = []
|
|
@@ -530,6 +531,23 @@ export const createStore = async <
|
|
|
530
531
|
void db.storageDb.execute(queryStr, preparedBindValues, undefined)
|
|
531
532
|
}
|
|
532
533
|
},
|
|
534
|
+
mutate: (...list) => {
|
|
535
|
+
for (const mutationEventDecoded of list) {
|
|
536
|
+
const mutationDef =
|
|
537
|
+
schema.mutations.get(mutationEventDecoded.mutation) ??
|
|
538
|
+
shouldNeverHappen(`Unknown mutation type: ${mutationEventDecoded.mutation}`)
|
|
539
|
+
|
|
540
|
+
const execArgsArr = getExecArgsFromMutation({ mutationDef, mutationEventDecoded })
|
|
541
|
+
// const { bindValues, statementSql } = getExecArgsFromMutation({ mutationDef, mutationEventDecoded })
|
|
542
|
+
|
|
543
|
+
for (const { statementSql, bindValues } of execArgsArr) {
|
|
544
|
+
db.mainDb.execute(statementSql, bindValues)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const mutationEventEncoded = Schema.encodeUnknownSync(mutationEventSchema)(mutationEventDecoded)
|
|
548
|
+
void db.storageDb.mutate(mutationEventEncoded, span)
|
|
549
|
+
}
|
|
550
|
+
},
|
|
533
551
|
select: (queryStr, bindValues) => {
|
|
534
552
|
const stmt = db.mainDb.prepare(queryStr)
|
|
535
553
|
const preparedBindValues = bindValues ? prepareBindValues(bindValues, queryStr) : undefined
|
|
@@ -570,7 +588,7 @@ export const createStore = async <
|
|
|
570
588
|
// Think about what to do about this case.
|
|
571
589
|
// await applySchema(db, schema)
|
|
572
590
|
return Store.createStore<TGraphQLContext, TSchema>(
|
|
573
|
-
{ db, schema, graphQLOptions, otelTracer, otelRootSpanContext, dbGraph },
|
|
591
|
+
{ db, schema, graphQLOptions, otelTracer, otelRootSpanContext, dbGraph, mutationEventSchema },
|
|
574
592
|
span,
|
|
575
593
|
)
|
|
576
594
|
} finally {
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { LiveQuery } from '../../reactiveQueries/base-class.js';
|
|
3
|
-
export type Props<TItem> = {
|
|
4
|
-
items$: LiveQuery<ReadonlyArray<TItem>>;
|
|
5
|
-
/**
|
|
6
|
-
* @example
|
|
7
|
-
* ```tsx
|
|
8
|
-
* renderContainer={(children) => <ul>{children}</ul>}
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
renderContainer: (ref: React.LegacyRef<any>) => React.ReactNode;
|
|
12
|
-
renderItem: (item: TItem, opts: {
|
|
13
|
-
index: number;
|
|
14
|
-
isInitialListRender: boolean;
|
|
15
|
-
}) => React.ReactNode;
|
|
16
|
-
getKey: (item: TItem, index: number) => string | number;
|
|
17
|
-
};
|
|
18
|
-
export declare const DiffableList: <TItem>({ items$, renderContainer, renderItem, getKey, }: Props<TItem>) => React.ReactNode;
|
|
19
|
-
//# sourceMappingURL=DiffableList%20copy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList copy.d.ts","sourceRoot":"","sources":["../../../src/react/components/DiffableList copy.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAUpE,MAAM,MAAM,KAAK,CAAC,KAAK,IAAI;IACzB,MAAM,EAAE,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;IACvC;;;;;OAKG;IACH,eAAe,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,SAAS,CAAA;IAE/D,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAA;IACnG,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;CACxD,CAAA;AAED,eAAO,MAAM,YAAY,4DAKtB,MAAM,KAAK,CAAC,KAAG,MAAM,SAwEvB,CAAA"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import * as million from 'million';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { computed } from '../../reactiveQueries/js.js';
|
|
4
|
-
import { useQuery } from '../useQuery.js';
|
|
5
|
-
export const DiffableList = ({ items$, renderContainer, renderItem, getKey, }) => {
|
|
6
|
-
const ref = React.useRef(null);
|
|
7
|
-
const container = renderContainer(ref);
|
|
8
|
-
const [hasMounted, setHasMounted] = React.useState(false);
|
|
9
|
-
React.useEffect(() => setHasMounted(true), []);
|
|
10
|
-
const keys$ = computed((get) => get(items$).map(getKey));
|
|
11
|
-
const elsRef = React.useRef([]);
|
|
12
|
-
// const ContextBridge = itsFine.useContextBridge()
|
|
13
|
-
// const { store } = useStore()
|
|
14
|
-
// const renderListEl = React.useCallback(
|
|
15
|
-
// (parentEl: HTMLElement, index: number, item$: LiveQuery<TItem>) => {
|
|
16
|
-
// const root = ReactDOM.createRoot(parentEl)
|
|
17
|
-
// root.render(
|
|
18
|
-
// // <ContextBridge>
|
|
19
|
-
// <LiveStoreContext.Provider value={{ store }}>
|
|
20
|
-
// <ItemWrapper item$={item$} renderItem={renderItem} opts={{ index, isInitialListRender: !hasMounted }} />
|
|
21
|
-
// </LiveStoreContext.Provider>,
|
|
22
|
-
// // </ContextBridge>,
|
|
23
|
-
// )
|
|
24
|
-
// return root
|
|
25
|
-
// },
|
|
26
|
-
// [hasMounted, renderItem, store],
|
|
27
|
-
// )
|
|
28
|
-
React.useLayoutEffect(() => {
|
|
29
|
-
if (ref.current === null) {
|
|
30
|
-
throw new Error('ref.current is null');
|
|
31
|
-
}
|
|
32
|
-
const keys = keys$.run();
|
|
33
|
-
const queries$ = keys.map((_key, index) => computed((get) => get(items$)[index]));
|
|
34
|
-
// const list = million.mapArray(
|
|
35
|
-
// queries$.map((item$, index) =>
|
|
36
|
-
// ItemWrapperBlock({
|
|
37
|
-
// item$,
|
|
38
|
-
// opts: { index, isInitialListRender: !hasMounted },
|
|
39
|
-
// renderItem,
|
|
40
|
-
// }),
|
|
41
|
-
// ),
|
|
42
|
-
// )
|
|
43
|
-
// million.mount(list, ref.current)
|
|
44
|
-
// const keys = keys$.run()
|
|
45
|
-
// for (let index = 0; index < keys.length; index++) {
|
|
46
|
-
// const parentEl = document.createElement('div')
|
|
47
|
-
// ref.current!.append(parentEl)
|
|
48
|
-
// const item$ = computed((get) => get(items$)[index]!) as LiveQuery<TItem>
|
|
49
|
-
// const root = renderListEl(parentEl, index, item$)
|
|
50
|
-
// elsRef.current.push({ el: parentEl, item$, root, id: keys[index]! })
|
|
51
|
-
// }
|
|
52
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
|
-
}, []);
|
|
54
|
-
React.useEffect(() => () => keys$.destroy(), [keys$]);
|
|
55
|
-
return React.createElement(React.Fragment, null, container);
|
|
56
|
-
};
|
|
57
|
-
const ItemWrapper = ({ item$, opts, renderItem, }) => {
|
|
58
|
-
const item = useQuery(item$);
|
|
59
|
-
return React.createElement(React.Fragment, null, renderItem(item, opts));
|
|
60
|
-
};
|
|
61
|
-
const ItemWrapperBlock = million.block(ItemWrapper);
|
|
62
|
-
//# sourceMappingURL=DiffableList%20copy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList copy.js","sourceRoot":"","sources":["../../../src/react/components/DiffableList copy.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAGtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAoBzC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAS,EACnC,MAAM,EACN,eAAe,EACf,UAAU,EACV,MAAM,GACO,EAAmB,EAAE;IAClC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAc,IAAI,CAAC,CAAA;IAC3C,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IAEtC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEzD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAE9C,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IAOxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAU,EAAE,CAAC,CAAA;IAExC,mDAAmD;IACnD,+BAA+B;IAE/B,0CAA0C;IAC1C,yEAAyE;IACzE,iDAAiD;IACjD,mBAAmB;IACnB,2BAA2B;IAC3B,sDAAsD;IACtD,mHAAmH;IACnH,sCAAsC;IACtC,6BAA6B;IAC7B,QAAQ;IAER,kBAAkB;IAClB,OAAO;IACP,qCAAqC;IACrC,IAAI;IAEJ,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE;QACzB,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;QACxC,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAA;QAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAE,CAAC,CAAuB,CAAA;QAExG,iCAAiC;QACjC,mCAAmC;QACnC,yBAAyB;QACzB,eAAe;QACf,2DAA2D;QAC3D,oBAAoB;QACpB,UAAU;QACV,OAAO;QACP,IAAI;QAEJ,mCAAmC;QAEnC,2BAA2B;QAE3B,sDAAsD;QACtD,mDAAmD;QACnD,kCAAkC;QAClC,6EAA6E;QAC7E,sDAAsD;QACtD,yEAAyE;QACzE,IAAI;QACJ,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAErD,OAAO,0CAAG,SAAS,CAAI,CAAA;AACzB,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAS,EAC3B,KAAK,EACL,IAAI,EACJ,UAAU,GAKX,EAAE,EAAE;IACH,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE5B,OAAO,0CAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAI,CAAA;AACtC,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,WAAkB,CAAC,CAAA"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { LiveQuery } from '../../reactiveQueries/base-class.js';
|
|
3
|
-
export type Props<TItem> = {
|
|
4
|
-
items$: LiveQuery<ReadonlyArray<TItem>>;
|
|
5
|
-
renderItem: (item: TItem, opts: {
|
|
6
|
-
index: number;
|
|
7
|
-
isInitialListRender: boolean;
|
|
8
|
-
}) => React.ReactNode;
|
|
9
|
-
/** Needs to be unique across all list items */
|
|
10
|
-
getKey: (item: TItem, index: number) => string | number;
|
|
11
|
-
};
|
|
12
|
-
export declare const DiffableList: <TItem>({ items$, renderItem, getKey }: Props<TItem>) => React.ReactNode;
|
|
13
|
-
//# sourceMappingURL=DiffableList.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList.d.ts","sourceRoot":"","sources":["../../../src/react/components/DiffableList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AASpE,MAAM,MAAM,KAAK,CAAC,KAAK,IAAI;IACzB,MAAM,EAAE,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;IAEvC,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAA;IACnG,+CAA+C;IAC/C,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;CACxD,CAAA;AAED,eAAO,MAAM,YAAY,0CAA4C,MAAM,KAAK,CAAC,KAAG,MAAM,SA6BzF,CAAA"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { computed } from '../../reactiveQueries/js.js';
|
|
3
|
-
import { useQuery } from '../useQuery.js';
|
|
4
|
-
import { useTemporaryQuery } from '../useTemporaryQuery.js';
|
|
5
|
-
export const DiffableList = ({ items$, renderItem, getKey }) => {
|
|
6
|
-
const [hasMounted, setHasMounted] = React.useState(false);
|
|
7
|
-
React.useEffect(() => setHasMounted(true), []);
|
|
8
|
-
const keysCb = React.useCallback(() => computed((get) => get(items$).map(getKey)), [getKey, items$]);
|
|
9
|
-
const keys = useTemporaryQuery(keysCb);
|
|
10
|
-
const arr = React.useMemo(() => keys.map((key) => [key, computed((get) => get(items$).find((item) => getKey(item, 0) === key))]), [getKey, items$, keys]);
|
|
11
|
-
return (React.createElement(React.Fragment, null, arr.map(([key, item$], index) => (React.createElement(ItemWrapperMemo, { key: key, itemKey: key, "item$": item$, opts: { isInitialListRender: !hasMounted, index }, renderItem: renderItem })))));
|
|
12
|
-
};
|
|
13
|
-
const ItemWrapper = ({ item$, opts, renderItem, }) => {
|
|
14
|
-
const item = useQuery(item$);
|
|
15
|
-
return React.createElement(React.Fragment, null, renderItem(item, opts));
|
|
16
|
-
};
|
|
17
|
-
const ItemWrapperMemo = React.memo(ItemWrapper, (prev, next) => prev.itemKey === next.itemKey &&
|
|
18
|
-
prev.renderItem === prev.renderItem &&
|
|
19
|
-
prev.opts.index === next.opts.index &&
|
|
20
|
-
prev.opts.isInitialListRender === next.opts.isInitialListRender);
|
|
21
|
-
//# sourceMappingURL=DiffableList.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList.js","sourceRoot":"","sources":["../../../src/react/components/DiffableList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAc3D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAgB,EAAmB,EAAE;IACpG,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEzD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAE9C,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACpG,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACtC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CACvB,GAAG,EAAE,CACH,IAAI,CAAC,GAAG,CACN,CAAC,GAAG,EAAE,EAAE,CACN,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,GAAG,CAAE,CAAqB,CAAU,CAC9G,EACH,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CACvB,CAAA;IAED,OAAO,CACL,0CACG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,oBAAC,eAAe,IACd,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,GAAG,WACL,KAAK,EACZ,IAAI,EAAE,EAAE,mBAAmB,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,EACjD,UAAU,EAAE,UAAU,GACtB,CACH,CAAC,CACD,CACJ,CAAA;AACH,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAS,EAC3B,KAAK,EACL,IAAI,EACJ,UAAU,GAMX,EAAE,EAAE;IACH,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE5B,OAAO,0CAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAI,CAAA;AACtC,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAChC,WAAW,EACX,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CACb,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;IAC7B,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU;IACnC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK;IACnC,IAAI,CAAC,IAAI,CAAC,mBAAmB,KAAK,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAC5C,CAAA"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { LiveQuery } from '../../reactiveQueries/base-class.js';
|
|
3
|
-
export type Props<TItem> = {
|
|
4
|
-
items$: LiveQuery<ReadonlyArray<TItem>>;
|
|
5
|
-
/**
|
|
6
|
-
* @example
|
|
7
|
-
* ```tsx
|
|
8
|
-
* renderContainer={(children) => <ul>{children}</ul>}
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
renderContainer: (ref: React.LegacyRef<any>) => React.ReactNode;
|
|
12
|
-
renderItem: (item: TItem, opts: {
|
|
13
|
-
index: number;
|
|
14
|
-
isInitialListRender: boolean;
|
|
15
|
-
}) => React.ReactNode;
|
|
16
|
-
getKey: (item: TItem, index: number) => string | number;
|
|
17
|
-
};
|
|
18
|
-
export declare const DiffableList_: <TItem>({ items$, renderContainer, renderItem, getKey, }: Props<TItem>) => React.ReactNode;
|
|
19
|
-
export declare const DiffableList2: <TItem>({ items$, renderContainer, renderItem, getKey, }: Props<TItem>) => React.ReactNode;
|
|
20
|
-
//# sourceMappingURL=DiffableList2.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList2.d.ts","sourceRoot":"","sources":["../../../src/react/components/DiffableList2.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAMpE,MAAM,MAAM,KAAK,CAAC,KAAK,IAAI;IACzB,MAAM,EAAE,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;IACvC;;;;;OAKG;IACH,eAAe,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,SAAS,CAAA;IAE/D,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAA;IACnG,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;CACxD,CAAA;AAED,eAAO,MAAM,aAAa,4DAKvB,MAAM,KAAK,CAAC,KAAG,MAAM,SA4IvB,CAAA;AAED,eAAO,MAAM,aAAa,4DAKvB,MAAM,KAAK,CAAC,KAAG,MAAM,SAIvB,CAAA"}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { FI } from '@livestore/fractional-index';
|
|
2
|
-
import { casesHandled } from '@livestore/utils';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import ReactDOM from 'react-dom/client';
|
|
5
|
-
import { computed } from '../../reactiveQueries/js.js';
|
|
6
|
-
import { LiveStoreContext, useStore } from '../LiveStoreContext.js';
|
|
7
|
-
import { useQuery } from '../useQuery.js';
|
|
8
|
-
export const DiffableList_ = ({ items$, renderContainer, renderItem, getKey, }) => {
|
|
9
|
-
const ref = React.useRef(null);
|
|
10
|
-
const container = renderContainer(ref);
|
|
11
|
-
const [hasMounted, setHasMounted] = React.useState(false);
|
|
12
|
-
React.useEffect(() => setHasMounted(true), []);
|
|
13
|
-
const keys$ = computed((get) => get(items$).map(getKey));
|
|
14
|
-
const elsRef = React.useRef([]);
|
|
15
|
-
// const ContextBridge = itsFine.useContextBridge()
|
|
16
|
-
const { store } = useStore();
|
|
17
|
-
const renderListEl = React.useCallback((parentEl, index, item$) => {
|
|
18
|
-
const root = ReactDOM.createRoot(parentEl);
|
|
19
|
-
root.render(
|
|
20
|
-
// <ContextBridge>
|
|
21
|
-
React.createElement(LiveStoreContext.Provider, { value: { store } },
|
|
22
|
-
React.createElement(ItemWrapper, { "item$": item$, renderItem: renderItem, opts: { index, isInitialListRender: !hasMounted } })));
|
|
23
|
-
return root;
|
|
24
|
-
}, [hasMounted, renderItem, store]);
|
|
25
|
-
React.useLayoutEffect(() => {
|
|
26
|
-
if (ref.current === null) {
|
|
27
|
-
throw new Error('ref.current is null');
|
|
28
|
-
}
|
|
29
|
-
const keys = keys$.run();
|
|
30
|
-
for (let index = 0; index < keys.length; index++) {
|
|
31
|
-
const parentEl = document.createElement('div');
|
|
32
|
-
ref.current.append(parentEl);
|
|
33
|
-
const item$ = computed((get) => get(items$)[index]);
|
|
34
|
-
const root = renderListEl(parentEl, index, item$);
|
|
35
|
-
elsRef.current.push({ el: parentEl, item$, root, id: keys[index] });
|
|
36
|
-
}
|
|
37
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
|
-
}, []);
|
|
39
|
-
React.useEffect(() => () => keys$.destroy(), [keys$]);
|
|
40
|
-
React.useEffect(() => {
|
|
41
|
-
// const keys = keys$.run()
|
|
42
|
-
return keys$.subscribe((keys) => {
|
|
43
|
-
const prevKeys = elsRef.current.map((el) => el.id);
|
|
44
|
-
let arrayIsEqual = true;
|
|
45
|
-
for (let i = 0; i < keys.length; i++) {
|
|
46
|
-
if (keys[i] !== prevKeys[i]) {
|
|
47
|
-
arrayIsEqual = false;
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (arrayIsEqual)
|
|
52
|
-
return;
|
|
53
|
-
const previousAgg = FI.aggregateMake(prevKeys, FI.fractionalIndexImplNumber);
|
|
54
|
-
const { newEvents } = FI.getNewEvents(previousAgg, keys, FI.fractionalIndexImplNumber);
|
|
55
|
-
console.log('newEvents', newEvents);
|
|
56
|
-
for (const event of newEvents) {
|
|
57
|
-
switch (event.op) {
|
|
58
|
-
case 'remove': {
|
|
59
|
-
const { index } = event;
|
|
60
|
-
const el = elsRef.current[index];
|
|
61
|
-
el.root.unmount();
|
|
62
|
-
el.el.remove();
|
|
63
|
-
el.item$.destroy();
|
|
64
|
-
elsRef.current.splice(index, 1);
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
case 'add': {
|
|
68
|
-
const { index } = event;
|
|
69
|
-
const parentEl = document.createElement('div');
|
|
70
|
-
ref.current.append(parentEl);
|
|
71
|
-
const item$ = computed((get) => get(items$)[index]);
|
|
72
|
-
const root = renderListEl(parentEl, index, item$);
|
|
73
|
-
elsRef.current.splice(index, 0, { el: parentEl, item$, root, id: keys[index] });
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
case 'move': {
|
|
77
|
-
// const { newIndex, previousIndex } = event
|
|
78
|
-
// const el = elsRef.current[previousIndex]!
|
|
79
|
-
// const item$ = el.item$
|
|
80
|
-
// const root = el.root
|
|
81
|
-
// const elEl = el.el
|
|
82
|
-
// elsRef.current.splice(previousIndex, 1)
|
|
83
|
-
// elsRef.current.splice(newIndex, 0, { el: elEl, item$, root })
|
|
84
|
-
// ref.current!.insertBefore(elEl, elsRef.current[newIndex + 1]?.el)
|
|
85
|
-
// // move dom element
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
default: {
|
|
89
|
-
casesHandled(event);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
// for (let index = 0; index < keys.length; index++) {
|
|
95
|
-
// if (prevKeys[index] === keys[index]) continue
|
|
96
|
-
// // check if `keys[index]` === `prevKeys[index + 1]`
|
|
97
|
-
// // which probably means that
|
|
98
|
-
// if (keys[index] === prevKeys[index + 1]) {
|
|
99
|
-
// // sp
|
|
100
|
-
// }
|
|
101
|
-
// prevKeys[index] = keys[index] as any
|
|
102
|
-
// }
|
|
103
|
-
// TODO in the future use a more efficient diffing algorithm that re-uses elements more optimally
|
|
104
|
-
// right now we're only looking one step ahead
|
|
105
|
-
// reconcile until `keys` and `prevKeys` are equal
|
|
106
|
-
// prevKeys = keys
|
|
107
|
-
}, [items$, keys$, renderListEl]);
|
|
108
|
-
return React.createElement(React.Fragment, null, container);
|
|
109
|
-
};
|
|
110
|
-
export const DiffableList2 = ({ items$, renderContainer, renderItem, getKey, }) => (
|
|
111
|
-
// <itsFine.FiberProvider>
|
|
112
|
-
React.createElement(DiffableList_, { "items$": items$, renderContainer: renderContainer, renderItem: renderItem, getKey: getKey })
|
|
113
|
-
// </itsFine.FiberProvider>
|
|
114
|
-
);
|
|
115
|
-
const ItemWrapper = ({ item$, opts, renderItem, }) => {
|
|
116
|
-
const item = useQuery(item$);
|
|
117
|
-
return React.createElement(React.Fragment, null, renderItem(item, opts));
|
|
118
|
-
};
|
|
119
|
-
//# sourceMappingURL=DiffableList2.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList2.js","sourceRoot":"","sources":["../../../src/react/components/DiffableList2.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { LiveQuery } from '../../reactiveQueries/base-class.js';
|
|
3
|
-
export type Props<TItem> = {
|
|
4
|
-
items$: LiveQuery<ReadonlyArray<TItem>>;
|
|
5
|
-
/**
|
|
6
|
-
* @example
|
|
7
|
-
* ```tsx
|
|
8
|
-
* renderContainer={(children) => <ul>{children}</ul>}
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
renderContainer: (ref: React.LegacyRef<any>) => React.ReactNode;
|
|
12
|
-
renderItem: (item: TItem, opts: {
|
|
13
|
-
index: number;
|
|
14
|
-
isInitialListRender: boolean;
|
|
15
|
-
}) => React.ReactNode;
|
|
16
|
-
getKey: (item: TItem, index: number) => string | number;
|
|
17
|
-
};
|
|
18
|
-
export declare const DiffableList: <TItem>({ items$, renderContainer, renderItem, getKey, }: Props<TItem>) => React.ReactNode;
|
|
19
|
-
//# sourceMappingURL=DiffableList3.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiffableList3.d.ts","sourceRoot":"","sources":["../../../src/react/components/DiffableList3.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAUpE,MAAM,MAAM,KAAK,CAAC,KAAK,IAAI;IACzB,MAAM,EAAE,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;IACvC;;;;;OAKG;IACH,eAAe,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,SAAS,CAAA;IAE/D,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAA;IACnG,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;CACxD,CAAA;AAED,eAAO,MAAM,YAAY,4DAKtB,MAAM,KAAK,CAAC,KAAG,MAAM,SAwEvB,CAAA"}
|