simplesvelte 2.4.10 → 2.5.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/dist/Grid.svelte CHANGED
@@ -14,15 +14,25 @@
14
14
 
15
15
  type Props = {
16
16
  gridEl?: HTMLDivElement
17
+ /** Bindable reference to the AG Grid API. Use `bind:gridApi` on the parent. */
18
+ gridApi?: GridApi
17
19
  gridData?: any[] // Replace with your actual data type
18
20
  gridOptions: GridOptions
21
+ /**
22
+ * localStorage key for automatic grid state persistence (filters, sorts, column widths).
23
+ * When set, state is saved on every change and restored on mount.
24
+ */
25
+ stateKey?: string
19
26
  class?: string
20
27
  }
21
- let { gridEl = $bindable(), gridData, gridOptions, class: gridClass = 'grow' }: Props = $props()
22
-
23
- // Register modules once
24
-
25
- let gridApi: GridApi | undefined
28
+ let {
29
+ gridEl = $bindable(),
30
+ gridApi = $bindable(),
31
+ gridData,
32
+ gridOptions,
33
+ stateKey,
34
+ class: gridClass = 'grow',
35
+ }: Props = $props()
26
36
  let initCheckInterval: ReturnType<typeof setInterval> | undefined
27
37
  let attemptCount = 0
28
38
 
@@ -49,10 +59,39 @@
49
59
  console.warn('⚠️ Grid: No license key found. Running in trial mode.')
50
60
  }
51
61
 
62
+ // Wrap onGridReady to expose the gridApi bindable and handle stateKey persistence,
63
+ // while still calling the user's own onGridReady callback if provided.
64
+ const userOnGridReady = gridOptions.onGridReady
65
+
66
+ // Load saved state upfront — must be in gridConfig.initialState, not applied post-init.
67
+ let savedState: object | undefined
68
+ if (stateKey) {
69
+ try {
70
+ const raw = localStorage.getItem(stateKey)
71
+ if (raw) savedState = JSON.parse(raw)
72
+ } catch {
73
+ /* ignore parse errors */
74
+ }
75
+ }
76
+
52
77
  const gridConfig = {
53
78
  ...gridOptions,
54
79
  theme: themeQuartz,
55
80
  ...(gridData !== undefined && { rowData: gridData }),
81
+ ...(savedState !== undefined && { initialState: savedState }),
82
+ onGridReady: (params: Parameters<NonNullable<GridOptions['onGridReady']>>[0]) => {
83
+ userOnGridReady?.(params)
84
+ gridApi = params.api
85
+ if (stateKey) {
86
+ params.api.addEventListener('stateUpdated', (e: any) => {
87
+ try {
88
+ localStorage.setItem(stateKey, JSON.stringify(e.state))
89
+ } catch {
90
+ /* ignore storage errors */
91
+ }
92
+ })
93
+ }
94
+ },
56
95
  }
57
96
 
58
97
  console.log('🎨 Grid: Creating grid instance...')
@@ -1,10 +1,17 @@
1
- import { type GridOptions } from 'ag-grid-enterprise';
1
+ import { type GridApi, type GridOptions } from 'ag-grid-enterprise';
2
2
  type Props = {
3
3
  gridEl?: HTMLDivElement;
4
+ /** Bindable reference to the AG Grid API. Use `bind:gridApi` on the parent. */
5
+ gridApi?: GridApi;
4
6
  gridData?: any[];
5
7
  gridOptions: GridOptions;
8
+ /**
9
+ * localStorage key for automatic grid state persistence (filters, sorts, column widths).
10
+ * When set, state is saved on every change and restored on mount.
11
+ */
12
+ stateKey?: string;
6
13
  class?: string;
7
14
  };
8
- declare const Grid: import("svelte").Component<Props, {}, "gridEl">;
15
+ declare const Grid: import("svelte").Component<Props, {}, "gridEl" | "gridApi">;
9
16
  type Grid = ReturnType<typeof Grid>;
10
17
  export default Grid;
package/dist/Input.svelte CHANGED
@@ -1,141 +1,145 @@
1
- <script lang="ts">
2
- import { SvelteDate } from 'svelte/reactivity'
3
- import Label from './Label.svelte'
4
- type Props = {
5
- value?: any
6
- name?: string
7
- label?: string
8
- class?: string
9
- required?: boolean
10
- disabled?: boolean
11
- element?: HTMLElement
12
- type?:
13
- | 'text'
14
- | 'number'
15
- | 'password'
16
- | 'email'
17
- | 'number'
18
- | 'tel'
19
- | 'url'
20
- | 'date'
21
- | 'datetime-local'
22
- | 'color'
23
- | 'file'
24
- | 'checkbox'
25
- error?: string
26
- hideOptional?: boolean
27
- zodErrors?: {
28
- expected: string
29
- code: string
30
- path: string[]
31
- message: string
32
- }[]
33
- [x: string]: any
34
- }
35
- let {
36
- value = $bindable(),
37
- element = $bindable(),
38
- label,
39
- type = 'text',
40
- name,
41
- required,
42
- disabled,
43
- class: myClass,
44
- error,
45
- hideOptional,
46
- zodErrors,
47
- ...rest
48
- }: Props = $props()
49
- function getValue() {
50
- if (type == 'date') {
51
- if (!value) return ''
52
- const dateString = new Date(value).toISOString().split('T')[0]
53
- return dateString
54
- } else if (type == 'datetime-local') {
55
- if (!value) return ''
56
- const date = new Date(value)
57
- const dateString = new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, -1)
58
- return dateString
59
- }
60
- return value ?? ''
61
- }
62
- function setValue(newValue: any) {
63
- if (type == 'number') {
64
- if (isNaN(Number(newValue))) {
65
- value = null
66
- } else {
67
- value = Number(newValue)
68
- }
69
- } else if (type == 'date') {
70
- const date = new SvelteDate(newValue)
71
- if (isNaN(date.getTime())) {
72
- value = null
73
- } else {
74
- date.setUTCHours(0, 0, 0, 0)
75
- value = date
76
- }
77
- } else if (type == 'datetime-local') {
78
- const date = new SvelteDate(newValue)
79
- if (isNaN(date.getTime())) {
80
- value = null
81
- } else {
82
- date.setSeconds(0, 0)
83
- value = date
84
- }
85
- } else {
86
- value = newValue
87
- }
88
- }
89
-
90
- // File input handlers - FileList is readonly
91
- function getFiles() {
92
- return value
93
- }
94
- function setFiles(fileList: FileList | null) {
95
- // FileList is readonly, so we just set it directly
96
- value = fileList
97
- }
98
-
99
- let inputClass = $derived.by(() => {
100
- if (type == 'file') return 'file-input w-full'
101
- if (type == 'checkbox') return 'checkbox checkbox-lg'
102
- return 'input w-full'
103
- })
104
-
105
- let showOptional = $derived.by(() => {
106
- if (hideOptional) return false
107
- return !required && !disabled && type != 'checkbox'
108
- })
109
-
110
- const errorText = $derived.by(() => {
111
- if (error) return error
112
- if (!name) return undefined
113
- if (zodErrors) return zodErrors.find((e) => e.path.includes(name))?.message
114
- return undefined
115
- })
116
- </script>
117
-
118
- <Label class={myClass} {label} {name} optional={showOptional} {disabled} error={errorText}>
119
- {#if type == 'checkbox'}
120
- <input bind:this={element} type="checkbox" {disabled} class={inputClass} {...rest} bind:checked={value} />
121
- {:else if type == 'file'}
122
- <input
123
- bind:this={element}
124
- {name}
125
- type="file"
126
- {disabled}
127
- {required}
128
- class={inputClass}
129
- {...rest}
130
- bind:files={getFiles, setFiles} />
131
- {:else}
132
- <input
133
- bind:this={element}
134
- {type}
135
- {disabled}
136
- {required}
137
- class="disabled:text-base-content disabled:!border-base-content/20 {inputClass} "
138
- {...rest}
139
- bind:value={getValue, setValue} />
140
- {/if}
141
- </Label>
1
+ <script lang="ts">
2
+ import { SvelteDate } from 'svelte/reactivity'
3
+ import Label from './Label.svelte'
4
+ type Props = {
5
+ value?: any
6
+ name?: string
7
+ label?: string
8
+ class?: string
9
+ required?: boolean
10
+ disabled?: boolean
11
+ element?: HTMLElement
12
+ type?:
13
+ | 'text'
14
+ | 'number'
15
+ | 'password'
16
+ | 'email'
17
+ | 'number'
18
+ | 'tel'
19
+ | 'url'
20
+ | 'date'
21
+ | 'datetime-local'
22
+ | 'color'
23
+ | 'file'
24
+ | 'checkbox'
25
+ error?: string
26
+ hideOptional?: boolean
27
+ zodErrors?: {
28
+ expected: string
29
+ code: string
30
+ path: string[]
31
+ message: string
32
+ }[]
33
+ [x: string]: any
34
+ }
35
+ let {
36
+ value = $bindable(),
37
+ element = $bindable(),
38
+ label,
39
+ type = 'text',
40
+ name,
41
+ required,
42
+ disabled,
43
+ class: myClass,
44
+ error,
45
+ hideOptional,
46
+ zodErrors,
47
+ ...rest
48
+ }: Props = $props()
49
+ function getValue() {
50
+ if (type == 'date') {
51
+ if (!value) return ''
52
+ const dateString = new Date(value).toISOString().split('T')[0]
53
+ return dateString
54
+ } else if (type == 'datetime-local') {
55
+ if (!value) return ''
56
+ const date = new Date(value)
57
+ const dateString = new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, -1)
58
+ return dateString
59
+ }
60
+ return value ?? ''
61
+ }
62
+ function setValue(newValue: any) {
63
+ if (type == 'number') {
64
+ if (isNaN(Number(newValue))) {
65
+ value = null
66
+ } else {
67
+ value = Number(newValue)
68
+ }
69
+ } else if (type == 'date') {
70
+ const date = new SvelteDate(newValue)
71
+ if (isNaN(date.getTime())) {
72
+ value = null
73
+ } else {
74
+ date.setUTCHours(0, 0, 0, 0)
75
+ value = date
76
+ }
77
+ } else if (type == 'datetime-local') {
78
+ const date = new SvelteDate(newValue)
79
+ if (isNaN(date.getTime())) {
80
+ value = null
81
+ } else {
82
+ date.setSeconds(0, 0)
83
+ value = date
84
+ }
85
+ } else {
86
+ value = newValue
87
+ }
88
+ }
89
+
90
+ // File input handlers - FileList is readonly
91
+ function getFiles() {
92
+ return value
93
+ }
94
+ function setFiles(fileList: FileList | null) {
95
+ // FileList is readonly, so we just set it directly
96
+ value = fileList
97
+ }
98
+
99
+ let inputClass = $derived.by(() => {
100
+ if (type == 'file') return 'file-input w-full'
101
+ if (type == 'checkbox') return 'checkbox checkbox-lg'
102
+ return 'input w-full'
103
+ })
104
+
105
+ let showOptional = $derived.by(() => {
106
+ if (hideOptional) return false
107
+ return !required && !disabled && type != 'checkbox'
108
+ })
109
+
110
+ const errorText = $derived.by(() => {
111
+ if (error) return error
112
+ if (!name) return undefined
113
+ if (zodErrors) return zodErrors.find((e) => e.path.includes(name))?.message
114
+ return undefined
115
+ })
116
+ </script>
117
+
118
+ {#if type != 'file'}
119
+ <input type="hidden" {name} value={value ?? ''} />
120
+ {/if}
121
+
122
+ <Label class={myClass} {label} {name} optional={showOptional} {disabled} error={errorText}>
123
+ {#if type == 'checkbox'}
124
+ <input bind:this={element} type="checkbox" {disabled} class={inputClass} {...rest} bind:checked={value} />
125
+ {:else if type == 'file'}
126
+ <input
127
+ bind:this={element}
128
+ {name}
129
+ type="file"
130
+ {disabled}
131
+ {required}
132
+ class={inputClass}
133
+ {...rest}
134
+ bind:files={getFiles, setFiles} />
135
+ {:else}
136
+ <input
137
+ bind:this={element}
138
+ {type}
139
+ {disabled}
140
+ {required}
141
+ class="disabled:text-base-content disabled:!border-base-content/20 {inputClass} "
142
+ {...rest}
143
+ bind:value={getValue, setValue} />
144
+ {/if}
145
+ </Label>
@@ -470,6 +470,15 @@
470
470
  }
471
471
  </script>
472
472
 
473
+ <!-- Data inputs for form submission -->
474
+ {#if multiple && Array.isArray(normalizedValue)}
475
+ {#each normalizedValue as val, i (val + '-' + i)}
476
+ <input type="hidden" {name} value={val} />
477
+ {/each}
478
+ {:else if !multiple && normalizedValue !== undefined && normalizedValue !== null && normalizedValue !== ''}
479
+ <input type="hidden" {name} value={normalizedValue} />
480
+ {/if}
481
+
473
482
  <Label {label} {name} optional={!required && !hideOptional} class={className} error={errorText}>
474
483
  {#if !disabled}
475
484
  <!-- Trigger button with popover target and anchor positioning -->
@@ -496,6 +496,32 @@ export type AGGridQueryConfig<TRecord = any> = {
496
496
  * ```
497
497
  */
498
498
  disableCaseInsensitive?: boolean;
499
+ /**
500
+ * Optional: Explicit field type declarations for correct filter coercion.
501
+ *
502
+ * Fixes cases where AG Grid sends numeric FK values or booleans as strings inside
503
+ * set/text filters, which Prisma then rejects or silently mismatches.
504
+ *
505
+ * Keys are column IDs exactly as used in AG Grid column definitions (dot-notation supported).
506
+ *
507
+ * Supported types:
508
+ * - `'number'` — coerces set-filter values via `Number()` and text-filter equals to `{ equals: Number(v) }`
509
+ * - `'boolean'` — forces the boolean path in set filters regardless of value shape
510
+ * - `'string'` — no-op (default behaviour, useful for explicit documentation)
511
+ *
512
+ * @example Eliminate numeric-FK transformWhere workarounds
513
+ * ```typescript
514
+ * // Before:
515
+ * transformWhere: (where) => {
516
+ * if (where.locationId?.in) where.locationId = { in: where.locationId.in.map(Number) }
517
+ * return where
518
+ * }
519
+ *
520
+ * // After:
521
+ * fieldTypes: { locationId: 'number', clientId: 'number', isActive: 'boolean' }
522
+ * ```
523
+ */
524
+ fieldTypes?: Record<string, 'number' | 'boolean' | 'string'>;
499
525
  };
500
526
  /**
501
527
  * Creates an AG Grid query handler for server-side data fetching
@@ -707,4 +733,48 @@ export declare const filterConfigs: {
707
733
  };
708
734
  };
709
735
  };
736
+ /**
737
+ * Creates merged GridOptions for a server-side row model grid.
738
+ *
739
+ * Combines `defaultSSRMGridOptions` + `defaultSSRMColDef` + datasource creation into one call.
740
+ * User overrides are merged on top of defaults; `defaultColDef` is deep-merged so individual
741
+ * column definition properties can be overridden without replacing the entire object.
742
+ *
743
+ * @param fetcher - Remote query function (or custom wrapper function for additional filters)
744
+ * @param overrides - GridOptions merged on top of defaults (columnDefs, callbacks, etc.)
745
+ * @param datasourceOptions - Optional options forwarded to `createAGGridDatasource` (onError, debug, etc.)
746
+ * @returns Merged GridOptions ready to pass to `<Grid {gridOptions} />`
747
+ *
748
+ * @example Basic usage
749
+ * ```svelte
750
+ * <script lang="ts">
751
+ * import { createSSRMOptions, Grid } from 'simplesvelte'
752
+ * import { getUsersGrid } from './user.remote'
753
+ * import type { GridApi } from 'ag-grid-enterprise'
754
+ *
755
+ * let gridApi = $state<GridApi>()
756
+ *
757
+ * const gridOptions = $derived(createSSRMOptions(getUsersGrid, {
758
+ * columnDefs: [
759
+ * { field: 'id' },
760
+ * { field: 'name', filter: 'agTextColumnFilter' },
761
+ * { field: 'department.name', headerName: 'Department', filter: 'agTextColumnFilter' },
762
+ * ],
763
+ * onRowClicked: (e) => { if (!e.node.group) console.log(e.data) },
764
+ * }))
765
+ * </script>
766
+ *
767
+ * <Grid {gridOptions} bind:gridApi stateKey="users-grid" />
768
+ * ```
769
+ *
770
+ * @example With a custom fetcher wrapper (additional filters)
771
+ * ```svelte
772
+ * <script lang="ts">
773
+ * let workOrderId = $props()
774
+ * const fetcher = (req: any) => getNotesByWorkOrderIdGrid({ ...req, workOrderId })
775
+ * const gridOptions = $derived(createSSRMOptions(fetcher, { columnDefs: [...] }))
776
+ * </script>
777
+ * ```
778
+ */
779
+ export declare function createSSRMOptions(fetcher: Parameters<typeof createAGGridDatasource>[0], overrides?: import('ag-grid-community').GridOptions, datasourceOptions?: Parameters<typeof createAGGridDatasource>[1]): import('ag-grid-community').GridOptions;
710
780
  export {};
@@ -357,9 +357,28 @@ function transformForPrisma(input) {
357
357
  /**
358
358
  * Handles text filters (contains, equals, startsWith, endsWith, etc.)
359
359
  */
360
- function applyTextFilter(where, field, filter, disableCaseInsensitive) {
360
+ function applyTextFilter(where, field, filter, disableCaseInsensitive, fieldType) {
361
361
  const type = filter.type;
362
362
  const value = filter.filter;
363
+ // When the field is declared as a number, coerce all text-filter values to numbers.
364
+ // Text filters don't make semantic sense on numeric fields; treat as equality.
365
+ if (fieldType === 'number') {
366
+ switch (type) {
367
+ case 'blank':
368
+ case 'empty':
369
+ where[field] = null;
370
+ return;
371
+ case 'notBlank':
372
+ where[field] = { not: null };
373
+ return;
374
+ case 'notEqual':
375
+ where[field] = { not: Number(value) };
376
+ return;
377
+ default:
378
+ where[field] = { equals: Number(value) };
379
+ return;
380
+ }
381
+ }
363
382
  switch (type) {
364
383
  case 'equals':
365
384
  where[field] = value;
@@ -504,7 +523,7 @@ function applyDateFilter(where, field, filter) {
504
523
  /**
505
524
  * Handles set filters (multi-select)
506
525
  */
507
- function applySetFilter(where, field, filter) {
526
+ function applySetFilter(where, field, filter, fieldType) {
508
527
  const values = filter.values;
509
528
  // If values array doesn't exist, skip this filter entirely (no filter applied)
510
529
  if (!values)
@@ -514,9 +533,22 @@ function applySetFilter(where, field, filter) {
514
533
  where[field] = { in: [] };
515
534
  return;
516
535
  }
517
- // Check if this is a boolean filter
536
+ // When fieldType is 'number', coerce all values to numbers before the `in` query.
537
+ // AG Grid sends numeric FK values as strings inside set filters.
538
+ if (fieldType === 'number') {
539
+ const converted = values.map(Number);
540
+ if (converted.length === 1) {
541
+ where[field] = converted[0];
542
+ }
543
+ else {
544
+ where[field] = { in: converted };
545
+ }
546
+ return;
547
+ }
548
+ // Check if this is a boolean filter.
549
+ // fieldType === 'boolean' forces the boolean path regardless of value shape.
518
550
  const booleanValues = new Set(['Yes', 'No', 'true', 'false', true, false]);
519
- const isBooleanFilter = values.every((v) => booleanValues.has(v));
551
+ const isBooleanFilter = fieldType === 'boolean' || values.every((v) => booleanValues.has(v));
520
552
  if (isBooleanFilter) {
521
553
  // Convert to boolean
522
554
  const converted = values.map((v) => v === 'Yes' || v === 'true' || v === true);
@@ -536,7 +568,7 @@ function applySetFilter(where, field, filter) {
536
568
  * Applies a filter to a field (main entry point)
537
569
  * Determines filterType first, then dispatches to appropriate handler
538
570
  */
539
- function applyFilterToField(where, field, filterValue, disableCaseInsensitive) {
571
+ function applyFilterToField(where, field, filterValue, disableCaseInsensitive, fieldType) {
540
572
  if (!filterValue || typeof filterValue !== 'object')
541
573
  return;
542
574
  const filter = filterValue;
@@ -544,7 +576,7 @@ function applyFilterToField(where, field, filterValue, disableCaseInsensitive) {
544
576
  const filterType = filter.filterType;
545
577
  switch (filterType) {
546
578
  case 'text':
547
- applyTextFilter(where, field, filter, disableCaseInsensitive);
579
+ applyTextFilter(where, field, filter, disableCaseInsensitive, fieldType);
548
580
  break;
549
581
  case 'number':
550
582
  applyNumberFilter(where, field, filter);
@@ -553,7 +585,7 @@ function applyFilterToField(where, field, filterValue, disableCaseInsensitive) {
553
585
  applyDateFilter(where, field, filter);
554
586
  break;
555
587
  case 'set':
556
- applySetFilter(where, field, filter);
588
+ applySetFilter(where, field, filter, fieldType);
557
589
  break;
558
590
  default:
559
591
  console.warn('Unknown filter type:', filterType, 'for field:', field, 'filter:', filter);
@@ -665,7 +697,7 @@ function buildWhereClause(request, config, groupKeys, rowGroupCols) {
665
697
  mergeWhereConditions(where, transformed);
666
698
  }
667
699
  else {
668
- applyFilterToField(where, columnId, filterValue, config.disableCaseInsensitive);
700
+ applyFilterToField(where, columnId, filterValue, config.disableCaseInsensitive, config.fieldTypes?.[columnId]);
669
701
  }
670
702
  }
671
703
  }
@@ -1140,3 +1172,58 @@ export const filterConfigs = {
1140
1172
  },
1141
1173
  },
1142
1174
  };
1175
+ // ============================================================================
1176
+ // Composite Grid Options Helper
1177
+ // ============================================================================
1178
+ /**
1179
+ * Creates merged GridOptions for a server-side row model grid.
1180
+ *
1181
+ * Combines `defaultSSRMGridOptions` + `defaultSSRMColDef` + datasource creation into one call.
1182
+ * User overrides are merged on top of defaults; `defaultColDef` is deep-merged so individual
1183
+ * column definition properties can be overridden without replacing the entire object.
1184
+ *
1185
+ * @param fetcher - Remote query function (or custom wrapper function for additional filters)
1186
+ * @param overrides - GridOptions merged on top of defaults (columnDefs, callbacks, etc.)
1187
+ * @param datasourceOptions - Optional options forwarded to `createAGGridDatasource` (onError, debug, etc.)
1188
+ * @returns Merged GridOptions ready to pass to `<Grid {gridOptions} />`
1189
+ *
1190
+ * @example Basic usage
1191
+ * ```svelte
1192
+ * <script lang="ts">
1193
+ * import { createSSRMOptions, Grid } from 'simplesvelte'
1194
+ * import { getUsersGrid } from './user.remote'
1195
+ * import type { GridApi } from 'ag-grid-enterprise'
1196
+ *
1197
+ * let gridApi = $state<GridApi>()
1198
+ *
1199
+ * const gridOptions = $derived(createSSRMOptions(getUsersGrid, {
1200
+ * columnDefs: [
1201
+ * { field: 'id' },
1202
+ * { field: 'name', filter: 'agTextColumnFilter' },
1203
+ * { field: 'department.name', headerName: 'Department', filter: 'agTextColumnFilter' },
1204
+ * ],
1205
+ * onRowClicked: (e) => { if (!e.node.group) console.log(e.data) },
1206
+ * }))
1207
+ * </script>
1208
+ *
1209
+ * <Grid {gridOptions} bind:gridApi stateKey="users-grid" />
1210
+ * ```
1211
+ *
1212
+ * @example With a custom fetcher wrapper (additional filters)
1213
+ * ```svelte
1214
+ * <script lang="ts">
1215
+ * let workOrderId = $props()
1216
+ * const fetcher = (req: any) => getNotesByWorkOrderIdGrid({ ...req, workOrderId })
1217
+ * const gridOptions = $derived(createSSRMOptions(fetcher, { columnDefs: [...] }))
1218
+ * </script>
1219
+ * ```
1220
+ */
1221
+ export function createSSRMOptions(fetcher, overrides, datasourceOptions) {
1222
+ const { defaultColDef: overrideColDef, ...restOverrides } = overrides ?? {};
1223
+ return {
1224
+ serverSideDatasource: createAGGridDatasource(fetcher, datasourceOptions),
1225
+ ...defaultSSRMGridOptions,
1226
+ defaultColDef: { ...defaultSSRMColDef, ...overrideColDef },
1227
+ ...restOverrides,
1228
+ };
1229
+ }
package/dist/index.d.ts CHANGED
@@ -6,5 +6,5 @@ export { default as Modal } from './Modal.svelte';
6
6
  export { default as Grid } from './Grid.svelte';
7
7
  export { Pop } from './pop.js';
8
8
  export { clickOutside, FormHelper, RoleHelper as roleHelper, formatDate } from './utils.js';
9
- export { createAGGridQuery, createAGGridDatasource, saveParams, fetchParams, type AGGridRequest, type AGGridResponse, type ComputedField, type AGGridQueryConfig, agGridRequestSchema, defaultAGGridRequest, defaultSSRMColDef, defaultSSRMGridOptions, filterConfigs, } from './ag-grid-refactored.js';
9
+ export { createAGGridQuery, createAGGridDatasource, createSSRMOptions, saveParams, fetchParams, type AGGridRequest, type AGGridResponse, type ComputedField, type AGGridQueryConfig, agGridRequestSchema, defaultAGGridRequest, defaultSSRMColDef, defaultSSRMGridOptions, filterConfigs, } from './ag-grid-refactored.js';
10
10
  import './styles.css';
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export { clickOutside, FormHelper, RoleHelper as roleHelper, formatDate } from '
9
9
  // AG Grid Server-Side Row Model API
10
10
  export {
11
11
  // Main functions
12
- createAGGridQuery, createAGGridDatasource,
12
+ createAGGridQuery, createAGGridDatasource, createSSRMOptions,
13
13
  // Parameter persistence functions
14
14
  saveParams, fetchParams,
15
15
  // Zod schema
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simplesvelte",
3
- "version": "2.4.10",
3
+ "version": "2.5.0",
4
4
  "scripts": {
5
5
  "dev": "bun vite dev",
6
6
  "build": "bun vite build && bun run prepack",