---
description: 
globs: 
alwaysApply: false
---
# Luckysheet Functionlist Error Prevention

**Root Cause Analysis:**
- Luckysheet internally references multiple functionlist objects at different namespaces
- Timing issues between library loading and object initialization
- Incomplete plugin.js loading which should initialize functionlist objects

## **Critical Loading Order (MUST Follow)**

```typescript
// ✅ DO: Complete library loading sequence
const loadSequence = async () => {
  // 1. jQuery (Luckysheet dependency)
  await loadResource("js", "https://code.jquery.com/jquery-3.6.0.min.js", "jquery");
  
  // 2. CSS files (in specific order)
  await loadResource("css", "/luckysheet/dist/plugins/css/pluginsCss.css", "plugins-css");
  await loadResource("css", "/luckysheet/dist/plugins/plugins.css", "plugins-main-css");
  await loadResource("css", "/luckysheet/dist/css/luckysheet.css", "luckysheet-css");
  await loadResource("css", "/luckysheet/dist/assets/iconfont/iconfont.css", "iconfont-css");
  
  // 3. LuckyExcel (for Excel file processing)
  await loadResource("js", "/luckysheet/dist/luckyexcel.umd.js", "luckyexcel");
  
  // 4. Plugin JS (CRITICAL: initializes functionlist)
  await loadResource("js", "/luckysheet/dist/plugins/js/plugin.js", "plugin-js");
  
  // 5. Luckysheet main library
  await loadResource("js", "/luckysheet/dist/luckysheet.umd.js", "luckysheet");
  
  // 6. CRITICAL: Wait for internal object initialization
  await new Promise(resolve => setTimeout(resolve, 1000));
};
```

## **Multi-Level Functionlist Initialization**

```typescript
// ✅ DO: Initialize all possible functionlist reference paths
const initializeFunctionlist = () => {
  try {
    // Level 1: Core Store objects
    if (!window.Store) window.Store = {};
    if (!window.Store.functionlist) window.Store.functionlist = [];
    if (!window.Store.luckysheet_function) window.Store.luckysheet_function = {};
    
    // Level 2: Global function objects
    if (!window.luckysheet_function) window.luckysheet_function = {};
    if (!window.functionlist) window.functionlist = [];
    
    // Level 3: Luckysheet internal objects
    if (window.luckysheet) {
      if (!window.luckysheet.functionlist) window.luckysheet.functionlist = [];
      if (!window.luckysheet.formula) window.luckysheet.formula = {};
      if (!window.luckysheet.formulaCache) window.luckysheet.formulaCache = {};
      if (!window.luckysheet.formulaObjects) window.luckysheet.formulaObjects = {};
    }
    
    // Level 4: Store internal structure
    if (!window.Store.config) window.Store.config = {};
    if (!window.Store.luckysheetfile) window.Store.luckysheetfile = [];
    if (!window.Store.currentSheetIndex) window.Store.currentSheetIndex = 0;
  } catch (error) {
    console.warn("Functionlist initialization warning:", error);
  }
};
```

## **TypeScript Window Interface Extension**

```typescript
// ✅ DO: Extend Window interface for all Luckysheet globals
declare global {
  interface Window {
    luckysheet: any;
    LuckyExcel: any;
    $: any; // jQuery
    Store: any; // Luckysheet Store
    luckysheet_function: any; // Luckysheet function list
    functionlist: any[]; // Global functionlist
  }
}
```

## **Critical Timing Requirements**

- **MUST** call `initializeFunctionlist()` at three points:
  1. After library loading sequence completion
  2. After 1000ms wait period for internal initialization
  3. Immediately before `luckysheet.create()` call

- **MUST** wait at least 1000ms after all libraries are loaded
- **MUST** verify all functionlist objects exist before calling `luckysheet.create()`

## **Error Recovery Pattern**

```typescript
// ✅ DO: Implement robust error recovery
try {
  // Final verification before luckysheet.create()
  initializeFunctionlist();
  
  // Verify critical objects exist
  const verificationResults = {
    store: !!window.Store,
    functionlist: !!window.Store?.functionlist,
    luckysheet: !!window.luckysheet,
    createFunction: typeof window.luckysheet?.create === "function"
  };
  
  if (!verificationResults.luckysheet || !verificationResults.createFunction) {
    throw new Error("Luckysheet not properly initialized");
  }
  
  window.luckysheet.create(options);
} catch (error) {
  console.error("Luckysheet initialization failed:", error);
  // Implement retry logic or fallback
}
```

## **Common Anti-Patterns to Avoid**

```typescript
// ❌ DON'T: Skip plugin.js loading
// plugin.js is CRITICAL for functionlist initialization

// ❌ DON'T: Use insufficient wait times
await new Promise(resolve => setTimeout(resolve, 100)); // TOO SHORT

// ❌ DON'T: Initialize only Store.functionlist
// Multiple objects need initialization

// ❌ DON'T: Call luckysheet.create() immediately after library load
// Internal objects need time to initialize
```

## **Debugging Checklist**

When functionlist errors occur:
1. ✅ Verify all libraries loaded in correct order
2. ✅ Check plugin.js is included and loaded
3. ✅ Confirm 1000ms wait after library loading
4. ✅ Verify all functionlist objects are arrays/objects (not undefined)
5. ✅ Check console for library loading errors
6. ✅ Ensure complete Luckysheet distribution is used (not partial)

## **Critical: Use Official LuckyExcel Pattern**

```typescript
// ✅ DO: Follow official LuckyExcel → Luckysheet pattern exactly
LuckyExcel.transformExcelToLucky(arrayBuffer, fileName, 
  // Success callback
  (exportJson: any, luckysheetfile: any) => {
    // CRITICAL: Use exportJson.sheets directly, no custom validation
    const luckysheetOptions = {
      container: 'luckysheet-container',
      data: exportJson.sheets,  // Direct usage - don't modify!
      title: exportJson.info?.name || fileName,
      userInfo: exportJson.info?.creator || "User",
      lang: "ko"
    };
    
    window.luckysheet.create(luckysheetOptions);
  },
  // Error callback
  (error: any) => {
    console.error("LuckyExcel conversion failed:", error);
  }
);
```

## **Anti-Pattern: Over-Processing Data**

```typescript
// ❌ DON'T: Modify or validate exportJson.sheets structure
const validatedSheets = exportJson.sheets.map(sheet => ({
  name: sheet?.name || `Sheet${index}`,
  data: Array.isArray(sheet?.data) ? sheet.data : [],
  // ... other modifications
}));

// ❌ DON'T: Use modified data
luckysheet.create({ data: validatedSheets });
```

The root cause of functionlist errors is often data structure mismatch between LuckyExcel output and Luckysheet expectations. Using exportJson.sheets directly maintains the proper internal structure that Luckysheet requires.

This pattern successfully resolves the "Cannot read properties of undefined (reading 'functionlist')" error by ensuring complete library loading sequence and multi-level functionlist initialization.
