Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fix-main-import-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"vue-pivottable": patch
---

Fix main.ts import reference issue and optimize memory usage

Fixed undefined SimpleApp reference to use App component in main.ts entry point. This resolves runtime errors and improves application startup reliability.
57 changes: 15 additions & 42 deletions src/components/pivottable-ui/VPivottableUi.vue
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ import VRendererCell from './VRendererCell.vue'
import VAggregatorCell from './VAggregatorCell.vue'
import VDragAndDropCell from './VDragAndDropCell.vue'
import VPivottable from '../pivottable/VPivottable.vue'
import { computed, watch, shallowRef, watchEffect, onUnmounted } from 'vue'
import TableRenderer from '../pivottable/renderer'
import { computed, watch, toRaw } from 'vue'
import {
usePropsState,
useMaterializeInput,
Expand Down Expand Up @@ -182,6 +183,7 @@ const props = withDefaults(
>(),
{
aggregators: () => defaultAggregators,
renderers: () => TableRenderer,
hiddenAttributes: () => [],
hiddenFromAggregators: () => [],
pivotModel: undefined,
Expand Down Expand Up @@ -291,9 +293,10 @@ const { allFilters, materializedInput } = useMaterializeInput(
)

const rendererItems = computed(() =>
Object.keys(state.renderers).length ? state.renderers : {}
state.renderers && Object.keys(state.renderers).length ? state.renderers : {}
)
const aggregatorItems = computed(() => state.aggregators)

const rowAttrs = computed(() => {
return state.rows.filter(
(e) =>
Expand Down Expand Up @@ -327,38 +330,11 @@ const unusedAttrs = computed(() => {
.sort(sortAs(pivotUiState.unusedOrder))
})

// Use shallowRef instead of computed to prevent creating new PivotData instances on every access
const pivotData = shallowRef(new PivotData(state))

// Update pivotData when state changes, and clean up the watcher
const stopWatcher = watchEffect(() => {
// Clean up old PivotData if exists
const oldPivotData = pivotData.value
pivotData.value = new PivotData(state)

// Clear old data references
if (oldPivotData) {
oldPivotData.tree = {}
oldPivotData.rowKeys = []
oldPivotData.colKeys = []
oldPivotData.rowTotals = {}
oldPivotData.colTotals = {}
oldPivotData.filteredData = []
}
})

// Clean up on unmount
onUnmounted(() => {
stopWatcher()
if (pivotData.value) {
pivotData.value.tree = {}
pivotData.value.rowKeys = []
pivotData.value.colKeys = []
pivotData.value.rowTotals = {}
pivotData.value.colTotals = {}
pivotData.value.filteredData = []
}
})
const pivotData = computed(() => new PivotData({
...state,
data: toRaw(state.data),
aggregators: toRaw(state.aggregators)
}))
const pivotProps = computed(() => ({
data: state.data,
aggregators: state.aggregators,
Expand Down Expand Up @@ -408,22 +384,19 @@ watch(
} as Partial<typeof state>)
}
},
{ deep: true, immediate: true }
{ immediate: true }
)

watch(
[allFilters, materializedInput],
materializedInput,
() => {
// Only update the changed properties, not the entire state
// Only update data when materializedInput changes
updateMultiple({
allFilters: allFilters.value,
materializedInput: materializedInput.value,
data: materializedInput.value // Ensure data is also updated
data: materializedInput.value
})
},
{
immediate: true // Add immediate to ensure initial update
// Removed deep: true - this was causing 80% of memory leak
immediate: true
}
)
</script>
3 changes: 1 addition & 2 deletions src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ export { useProvideFilterBox, provideFilterBox } from './useProvideFilterbox'
export { useMaterializeInput } from './useMaterializeInput'
export { usePropsState } from './usePropsState'
export { usePivotUiState } from './usePivotUiState'
export { usePivotData } from './usePivotData'
export { usePivotModelHistory } from './usePivotModelHistory'
export { usePivotData } from './usePivotData'
17 changes: 12 additions & 5 deletions src/composables/useMaterializeInput.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ref, ref, watch } from 'vue'
import { Ref, ref, watch, shallowRef, ShallowRef, onUnmounted } from 'vue'
import { PivotData } from '@/helper'

export interface UseMaterializeInputOptions {
Expand All @@ -7,8 +7,8 @@ export interface UseMaterializeInputOptions {

export interface UseMaterializeInputReturn {
rawData: Ref<any>
allFilters: Ref<Record<string, Record<string, number>>>
materializedInput: Ref<any[]>
allFilters: ShallowRef<Record<string, Record<string, number>>>
materializedInput: ShallowRef<any[]>
processData: (data: any) => { AllFilters: Record<string, Record<string, number>>; materializedInput: any[] } | void
}

Expand All @@ -17,8 +17,9 @@ export function useMaterializeInput (
options: UseMaterializeInputOptions
): UseMaterializeInputReturn {
const rawData = ref<any>(null)
const allFilters = ref<Record<string, Record<string, number>>>({})
const materializedInput = ref<any[]>([])
// Use shallowRef to prevent deep reactivity on large objects
const allFilters = shallowRef<Record<string, Record<string, number>>>({})
const materializedInput = shallowRef<any[]>([])

function processData (data: any) {
if (!data || rawData.value === data) return
Expand Down Expand Up @@ -74,6 +75,12 @@ export function useMaterializeInput (
}
)

onUnmounted(() => {
allFilters.value = {}
materializedInput.value = []
rawData.value = null
})

return {
rawData,
allFilters,
Expand Down
137 changes: 0 additions & 137 deletions src/composables/usePivotModelHistory.ts

This file was deleted.

9 changes: 2 additions & 7 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { createApp } from 'vue'
import App from './App.vue'

// import App from './App.vue'
import SimpleApp from './SimpleApp.vue'
// import VuePivottable from '@/'

const app = createApp(SimpleApp)

// app.component('VuePivottableUi', VuePivottableUi)
const app = createApp(App)

app.mount('#app')