@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.55
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/CHANGELOG.md +12 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md
CHANGED
|
@@ -1,503 +1,503 @@
|
|
|
1
|
-
# Module 5: Performance Optimization & Large Files
|
|
2
|
-
|
|
3
|
-
**Level:** Advanced
|
|
4
|
-
**Estimated Time:** 20 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
Learn how to handle large files efficiently and optimize file operation performance using batch processing, memory management, and parallel operations.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Understand memory-efficient file processing strategies
|
|
14
|
-
- ✅ Implement batch processing for multiple files
|
|
15
|
-
- ✅ Handle large files without running out of memory
|
|
16
|
-
- ✅ Optimize parallel file operations
|
|
17
|
-
- ✅ Monitor performance metrics
|
|
18
|
-
|
|
19
|
-
## Important Note About Streaming
|
|
20
|
-
|
|
21
|
-
⚠️ **The SDK does not currently provide built-in streaming methods.**
|
|
22
|
-
|
|
23
|
-
Both `S3DataSource` and `SftpDataSource` use `downloadFile()` which returns the entire file content as a `string` or `Buffer`. For large files, you need to implement your own processing strategies using the techniques below.
|
|
24
|
-
|
|
25
|
-
## File Size Guidelines
|
|
26
|
-
|
|
27
|
-
| File Size | Strategy | Memory Impact | Recommendation |
|
|
28
|
-
|-----------|----------|---------------|----------------|
|
|
29
|
-
| < 10 MB | Direct download | ~File size | ✅ Use `downloadFile()` directly |
|
|
30
|
-
| 10-100 MB | Download + process in chunks | ~File size | ⚠️ Process in batches, clear memory |
|
|
31
|
-
| 100-500 MB | Download with memory management | ~File size | ⚠️ Use Buffer, process in chunks, monitor memory |
|
|
32
|
-
| > 500 MB | Avoid direct download | Very high | 🔴 Split files at source if possible |
|
|
33
|
-
|
|
34
|
-
## Memory-Efficient Processing Strategies
|
|
35
|
-
|
|
36
|
-
### Strategy 1: Process Downloaded Files in Chunks
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
import { S3DataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
40
|
-
|
|
41
|
-
async function processLargeFileInChunks(s3: S3DataSource, key: string) {
|
|
42
|
-
// Download as Buffer to handle binary/large files (S3 uses encoding: 'binary')
|
|
43
|
-
const fileBuffer = await s3.downloadFile(key, { encoding: 'binary' });
|
|
44
|
-
|
|
45
|
-
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
46
|
-
let offset = 0;
|
|
47
|
-
let recordCount = 0;
|
|
48
|
-
|
|
49
|
-
while (offset < fileBuffer.length) {
|
|
50
|
-
const chunk = fileBuffer.slice(offset, offset + chunkSize);
|
|
51
|
-
const chunkStr = chunk.toString('utf8');
|
|
52
|
-
|
|
53
|
-
// Process chunk line-by-line
|
|
54
|
-
const lines = chunkStr.split('\n');
|
|
55
|
-
|
|
56
|
-
for (const line of lines) {
|
|
57
|
-
if (line.trim()) {
|
|
58
|
-
await processRecord(line);
|
|
59
|
-
recordCount++;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
offset += chunkSize;
|
|
64
|
-
|
|
65
|
-
// Log progress
|
|
66
|
-
if (recordCount % 10000 === 0) {
|
|
67
|
-
console.log(`Processed ${recordCount} records...`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
console.log(`Total records: ${recordCount}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function processRecord(line: string): Promise<void> {
|
|
75
|
-
// Your processing logic
|
|
76
|
-
const data = JSON.parse(line);
|
|
77
|
-
// ... handle data
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Strategy 2: Download with Size Limit
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
// SFTP supports maxSize option to prevent large downloads
|
|
85
|
-
async function safeDownload(sftp: SftpDataSource, path: string) {
|
|
86
|
-
try {
|
|
87
|
-
const content = await sftp.downloadFile(path, {
|
|
88
|
-
maxSize: 100 * 1024 * 1024 // 100 MB limit
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
return content;
|
|
92
|
-
|
|
93
|
-
} catch (error: any) {
|
|
94
|
-
if (error.message.includes('exceeds maximum')) {
|
|
95
|
-
console.error(`File ${path} is too large (> 100MB)`);
|
|
96
|
-
// Handle oversized file (skip, split, etc.)
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Strategy 3: Line-by-Line Processing from Buffer
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
async function processCSVFromBuffer(content: string | Buffer) {
|
|
108
|
-
const text = typeof content === 'string' ? content : content.toString('utf8');
|
|
109
|
-
const lines = text.split('\n');
|
|
110
|
-
|
|
111
|
-
const results: any[] = [];
|
|
112
|
-
|
|
113
|
-
for (let i = 0; i < lines.length; i++) {
|
|
114
|
-
const line = lines[i].trim();
|
|
115
|
-
|
|
116
|
-
if (!line) continue; // Skip empty lines
|
|
117
|
-
|
|
118
|
-
const record = parseCSVLine(line);
|
|
119
|
-
results.push(record);
|
|
120
|
-
|
|
121
|
-
// Clear memory periodically
|
|
122
|
-
if (results.length >= 10000) {
|
|
123
|
-
await processBatch(results);
|
|
124
|
-
results.length = 0; // Clear array
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Process remaining records
|
|
129
|
-
if (results.length > 0) {
|
|
130
|
-
await processBatch(results);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function parseCSVLine(line: string): any {
|
|
135
|
-
const fields = line.split(',');
|
|
136
|
-
return {
|
|
137
|
-
sku: fields[0],
|
|
138
|
-
qty: parseInt(fields[1], 10),
|
|
139
|
-
location: fields[2]
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async function processBatch(records: any[]): Promise<void> {
|
|
144
|
-
console.log(`Processing batch of ${records.length} records...`);
|
|
145
|
-
// Your batch processing logic
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## Batch File Processing
|
|
150
|
-
|
|
151
|
-
### Parallel Processing with Controlled Concurrency
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
import { S3DataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
155
|
-
|
|
156
|
-
async function processManyFilesInParallel(s3: S3DataSource, prefix: string) {
|
|
157
|
-
const files = await s3.listFiles({ prefix });
|
|
158
|
-
|
|
159
|
-
const concurrency = 10; // Process 10 files at once
|
|
160
|
-
|
|
161
|
-
for (let i = 0; i < files.length; i += concurrency) {
|
|
162
|
-
const batch = files.slice(i, i + concurrency);
|
|
163
|
-
|
|
164
|
-
await Promise.all(
|
|
165
|
-
batch.map(async (file) => {
|
|
166
|
-
try {
|
|
167
|
-
console.log(`Processing ${file.name}...`);
|
|
168
|
-
|
|
169
|
-
const content = await s3.downloadFile(file.name);
|
|
170
|
-
const result = await transformData(content);
|
|
171
|
-
|
|
172
|
-
// Upload result
|
|
173
|
-
await s3.uploadFile(
|
|
174
|
-
file.name.replace('incoming/', 'output/'),
|
|
175
|
-
JSON.stringify(result),
|
|
176
|
-
{ contentType: 'application/json' }
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
// Archive original
|
|
180
|
-
await s3.moveFile(
|
|
181
|
-
file.name,
|
|
182
|
-
file.name.replace('incoming/', 'archive/'),
|
|
183
|
-
true // deleteSource
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
console.log(`✓ Completed ${file.name}`);
|
|
187
|
-
|
|
188
|
-
} catch (error: any) {
|
|
189
|
-
console.error(`✗ Failed ${file.name}:`, error.message);
|
|
190
|
-
}
|
|
191
|
-
})
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
console.log(`Completed batch ${Math.floor(i / concurrency) + 1}/${Math.ceil(files.length / concurrency)}`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async function transformData(content: string): Promise<any> {
|
|
199
|
-
// Your transformation logic
|
|
200
|
-
return { processed: true, data: content };
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Sequential Processing for Memory-Constrained Environments
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
async function processFilesSequentially(s3: S3DataSource, prefix: string) {
|
|
208
|
-
const files = await s3.listFiles({ prefix });
|
|
209
|
-
|
|
210
|
-
let successCount = 0;
|
|
211
|
-
let failureCount = 0;
|
|
212
|
-
|
|
213
|
-
for (const file of files) {
|
|
214
|
-
try {
|
|
215
|
-
console.log(`Processing ${file.name}...`);
|
|
216
|
-
|
|
217
|
-
// Download and process one file at a time
|
|
218
|
-
const content = await s3.downloadFile(file.name);
|
|
219
|
-
await processFileContent(content, file.name);
|
|
220
|
-
|
|
221
|
-
// Move to archive
|
|
222
|
-
await s3.moveFile(
|
|
223
|
-
file.name,
|
|
224
|
-
file.name.replace('incoming/', 'archive/'),
|
|
225
|
-
true
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
successCount++;
|
|
229
|
-
|
|
230
|
-
// Force garbage collection hint (Node.js)
|
|
231
|
-
if (global.gc) {
|
|
232
|
-
global.gc();
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
} catch (error: any) {
|
|
236
|
-
console.error(`Failed ${file.name}:`, error.message);
|
|
237
|
-
failureCount++;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
console.log(`\nResults: ${successCount} succeeded, ${failureCount} failed`);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
async function processFileContent(content: string, fileName: string): Promise<void> {
|
|
245
|
-
// Process content line by line to manage memory
|
|
246
|
-
const lines = content.split('\n');
|
|
247
|
-
console.log(` Processing ${lines.length} lines...`);
|
|
248
|
-
|
|
249
|
-
for (const line of lines) {
|
|
250
|
-
if (line.trim()) {
|
|
251
|
-
// Process each line
|
|
252
|
-
await handleLine(line);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async function handleLine(line: string): Promise<void> {
|
|
258
|
-
// Your line processing logic
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
## SFTP Connection Pooling
|
|
263
|
-
|
|
264
|
-
### Reuse Connections for Better Performance
|
|
265
|
-
|
|
266
|
-
```typescript
|
|
267
|
-
import { SftpDataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
268
|
-
|
|
269
|
-
// ✅ GOOD: Reuse connection for multiple operations
|
|
270
|
-
async function processMultipleFilesSftpReuse(config: any, logger: any) {
|
|
271
|
-
const sftp = new SftpDataSource(config, logger);
|
|
272
|
-
|
|
273
|
-
try {
|
|
274
|
-
const files = await sftp.listFiles({ remotePath: '/incoming' });
|
|
275
|
-
|
|
276
|
-
for (const file of files) {
|
|
277
|
-
const content = await sftp.downloadFile(file.path);
|
|
278
|
-
await processData(content);
|
|
279
|
-
|
|
280
|
-
// Move to processed folder
|
|
281
|
-
await sftp.moveFile(
|
|
282
|
-
file.path,
|
|
283
|
-
file.path.replace('/incoming/', '/processed/'),
|
|
284
|
-
false // Don't overwrite
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
} finally {
|
|
289
|
-
await sftp.dispose(); // Close connection once
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// ❌ BAD: Create new connection for each file
|
|
294
|
-
async function processMultipleFilesSftpSlow(config: any, logger: any, files: any[]) {
|
|
295
|
-
for (const file of files) {
|
|
296
|
-
const sftp = new SftpDataSource(config, logger);
|
|
297
|
-
|
|
298
|
-
try {
|
|
299
|
-
const content = await sftp.downloadFile(file.path);
|
|
300
|
-
await processData(content);
|
|
301
|
-
} finally {
|
|
302
|
-
await sftp.dispose(); // Expensive connection overhead!
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
async function processData(content: string | Buffer): Promise<void> {
|
|
308
|
-
// Your processing logic
|
|
309
|
-
}
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
## Performance Monitoring
|
|
313
|
-
|
|
314
|
-
### Track Processing Metrics
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
interface ProcessingMetrics {
|
|
318
|
-
filesProcessed: number;
|
|
319
|
-
filesSkipped: number;
|
|
320
|
-
filesFailed: number;
|
|
321
|
-
totalBytes: number;
|
|
322
|
-
totalRecords: number;
|
|
323
|
-
startTime: number;
|
|
324
|
-
endTime?: number;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
async function processWithMetrics(s3: S3DataSource, prefix: string) {
|
|
328
|
-
const metrics: ProcessingMetrics = {
|
|
329
|
-
filesProcessed: 0,
|
|
330
|
-
filesSkipped: 0,
|
|
331
|
-
filesFailed: 0,
|
|
332
|
-
totalBytes: 0,
|
|
333
|
-
totalRecords: 0,
|
|
334
|
-
startTime: Date.now()
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
const files = await s3.listFiles({ prefix });
|
|
338
|
-
console.log(`Found ${files.length} files to process\n`);
|
|
339
|
-
|
|
340
|
-
for (const file of files) {
|
|
341
|
-
try {
|
|
342
|
-
// Skip non-CSV files
|
|
343
|
-
if (!file.name.endsWith('.csv')) {
|
|
344
|
-
metrics.filesSkipped++;
|
|
345
|
-
console.log(`⊘ Skipped ${file.name} (not CSV)`);
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
const content = await s3.downloadFile(file.name);
|
|
350
|
-
metrics.totalBytes += content.length;
|
|
351
|
-
|
|
352
|
-
const lines = content.split('\n').filter(l => l.trim());
|
|
353
|
-
metrics.totalRecords += lines.length;
|
|
354
|
-
|
|
355
|
-
await processFileData(content);
|
|
356
|
-
|
|
357
|
-
metrics.filesProcessed++;
|
|
358
|
-
console.log(`✓ Processed ${file.name} (${lines.length} records)`);
|
|
359
|
-
|
|
360
|
-
} catch (error: any) {
|
|
361
|
-
metrics.filesFailed++;
|
|
362
|
-
console.error(`✗ Failed ${file.name}:`, error.message);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
metrics.endTime = Date.now();
|
|
367
|
-
printMetrics(metrics);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
function printMetrics(metrics: ProcessingMetrics): void {
|
|
371
|
-
const duration = ((metrics.endTime! - metrics.startTime) / 1000).toFixed(2);
|
|
372
|
-
const throughputMBps = (metrics.totalBytes / (1024 * 1024) / parseFloat(duration)).toFixed(2);
|
|
373
|
-
const throughputRecSec = (metrics.totalRecords / parseFloat(duration)).toFixed(0);
|
|
374
|
-
|
|
375
|
-
console.log('\n' + '='.repeat(50));
|
|
376
|
-
console.log('Processing Metrics:');
|
|
377
|
-
console.log('='.repeat(50));
|
|
378
|
-
console.log(`Files Processed: ${metrics.filesProcessed}`);
|
|
379
|
-
console.log(`Files Skipped: ${metrics.filesSkipped}`);
|
|
380
|
-
console.log(`Files Failed: ${metrics.filesFailed}`);
|
|
381
|
-
console.log(`Total Records: ${metrics.totalRecords}`);
|
|
382
|
-
console.log(`Total Data: ${(metrics.totalBytes / (1024 * 1024)).toFixed(2)} MB`);
|
|
383
|
-
console.log(`Duration: ${duration}s`);
|
|
384
|
-
console.log(`Throughput: ${throughputMBps} MB/s`);
|
|
385
|
-
console.log(`Records/Second: ${throughputRecSec}`);
|
|
386
|
-
console.log('='.repeat(50) + '\n');
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
async function processFileData(content: string): Promise<void> {
|
|
390
|
-
// Your processing logic
|
|
391
|
-
}
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
## Memory Management Tips
|
|
395
|
-
|
|
396
|
-
### 1. Use Binary Mode for Large Files
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
// For large files, use Buffer to avoid string conversion overhead
|
|
400
|
-
// S3: use encoding: 'binary'
|
|
401
|
-
const buffer = await s3.downloadFile(key, { encoding: 'binary' });
|
|
402
|
-
|
|
403
|
-
// SFTP: use asBuffer: true
|
|
404
|
-
const buffer = await sftp.downloadFile(path, { asBuffer: true });
|
|
405
|
-
|
|
406
|
-
// Process buffer directly
|
|
407
|
-
processBuffer(buffer);
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### 2. Clear Large Arrays Periodically
|
|
411
|
-
|
|
412
|
-
```typescript
|
|
413
|
-
const results: any[] = [];
|
|
414
|
-
|
|
415
|
-
for (const record of records) {
|
|
416
|
-
results.push(transformRecord(record));
|
|
417
|
-
|
|
418
|
-
// Clear memory every 10,000 records
|
|
419
|
-
if (results.length >= 10000) {
|
|
420
|
-
await writeToDestination(results);
|
|
421
|
-
results.length = 0; // Clear array to free memory
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
### 3. Process Files in Batches
|
|
427
|
-
|
|
428
|
-
```typescript
|
|
429
|
-
// Instead of loading all files at once:
|
|
430
|
-
const files = await s3.listFiles({ prefix: 'data/' });
|
|
431
|
-
|
|
432
|
-
// Process in batches of 100
|
|
433
|
-
for (let i = 0; i < files.length; i += 100) {
|
|
434
|
-
const batch = files.slice(i, i + 100);
|
|
435
|
-
await Promise.all(batch.map(f => processFile(f)));
|
|
436
|
-
|
|
437
|
-
// Give GC a chance to run
|
|
438
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
439
|
-
}
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
### 4. Use Deno/Versori Buffer Import
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
// CRITICAL for Deno/Versori runtime
|
|
446
|
-
import { Buffer } from 'node:buffer';
|
|
447
|
-
|
|
448
|
-
const buffer = Buffer.from(content, 'utf8');
|
|
449
|
-
// ... use buffer
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
## Performance Comparison
|
|
453
|
-
|
|
454
|
-
### Download Methods
|
|
455
|
-
|
|
456
|
-
```typescript
|
|
457
|
-
// Small files (< 10 MB): Direct string download
|
|
458
|
-
const content = await s3.downloadFile('small.csv'); // Fast
|
|
459
|
-
const lines = content.split('\n');
|
|
460
|
-
|
|
461
|
-
// Large files (> 10 MB): Binary download + chunk processing
|
|
462
|
-
const buffer = await s3.downloadFile('large.csv', { encoding: 'binary' });
|
|
463
|
-
processInChunks(buffer, 1024 * 1024); // 1 MB chunks
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
### Parallel vs Sequential
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
// Parallel (fast, high memory)
|
|
470
|
-
await Promise.all(files.map(f => processFile(f)));
|
|
471
|
-
|
|
472
|
-
// Sequential (slow, low memory)
|
|
473
|
-
for (const file of files) {
|
|
474
|
-
await processFile(file);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// Batched parallel (balanced)
|
|
478
|
-
for (let i = 0; i < files.length; i += 10) {
|
|
479
|
-
await Promise.all(files.slice(i, i + 10).map(f => processFile(f)));
|
|
480
|
-
}
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
## Key Takeaways
|
|
484
|
-
|
|
485
|
-
- 🎯 SDK does not provide built-in streaming - use download + chunk processing
|
|
486
|
-
- 🎯 Use `encoding: 'binary'` (S3) or `asBuffer: true` (SFTP) for large files to avoid string conversion overhead
|
|
487
|
-
- 🎯 Process files in chunks to maintain constant memory usage
|
|
488
|
-
- 🎯 Use parallel processing with controlled batch sizes (10-20 files at once)
|
|
489
|
-
- 🎯 Reuse SFTP connections for multiple operations
|
|
490
|
-
- 🎯 Monitor metrics to identify bottlenecks
|
|
491
|
-
- 🎯 Clear large arrays periodically to prevent memory buildup
|
|
492
|
-
- 🎯 Use `maxSize` option in SFTP to prevent downloading oversized files
|
|
493
|
-
|
|
494
|
-
## Next Steps
|
|
495
|
-
|
|
496
|
-
Continue to [Module 6: Archive Patterns](./file-operations-06-archive-patterns.md) for advanced archiving workflows.
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
**Related Resources:**
|
|
501
|
-
- [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md) - Performance tips
|
|
502
|
-
- [Module 7: Testing & Troubleshooting](./file-operations-07-testing-troubleshooting.md) - Memory issues
|
|
503
|
-
- [Common Patterns](../examples/common-patterns.ts) - Copy-paste ready snippets
|
|
1
|
+
# Module 5: Performance Optimization & Large Files
|
|
2
|
+
|
|
3
|
+
**Level:** Advanced
|
|
4
|
+
**Estimated Time:** 20 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Learn how to handle large files efficiently and optimize file operation performance using batch processing, memory management, and parallel operations.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Understand memory-efficient file processing strategies
|
|
14
|
+
- ✅ Implement batch processing for multiple files
|
|
15
|
+
- ✅ Handle large files without running out of memory
|
|
16
|
+
- ✅ Optimize parallel file operations
|
|
17
|
+
- ✅ Monitor performance metrics
|
|
18
|
+
|
|
19
|
+
## Important Note About Streaming
|
|
20
|
+
|
|
21
|
+
⚠️ **The SDK does not currently provide built-in streaming methods.**
|
|
22
|
+
|
|
23
|
+
Both `S3DataSource` and `SftpDataSource` use `downloadFile()` which returns the entire file content as a `string` or `Buffer`. For large files, you need to implement your own processing strategies using the techniques below.
|
|
24
|
+
|
|
25
|
+
## File Size Guidelines
|
|
26
|
+
|
|
27
|
+
| File Size | Strategy | Memory Impact | Recommendation |
|
|
28
|
+
|-----------|----------|---------------|----------------|
|
|
29
|
+
| < 10 MB | Direct download | ~File size | ✅ Use `downloadFile()` directly |
|
|
30
|
+
| 10-100 MB | Download + process in chunks | ~File size | ⚠️ Process in batches, clear memory |
|
|
31
|
+
| 100-500 MB | Download with memory management | ~File size | ⚠️ Use Buffer, process in chunks, monitor memory |
|
|
32
|
+
| > 500 MB | Avoid direct download | Very high | 🔴 Split files at source if possible |
|
|
33
|
+
|
|
34
|
+
## Memory-Efficient Processing Strategies
|
|
35
|
+
|
|
36
|
+
### Strategy 1: Process Downloaded Files in Chunks
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { S3DataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
40
|
+
|
|
41
|
+
async function processLargeFileInChunks(s3: S3DataSource, key: string) {
|
|
42
|
+
// Download as Buffer to handle binary/large files (S3 uses encoding: 'binary')
|
|
43
|
+
const fileBuffer = await s3.downloadFile(key, { encoding: 'binary' });
|
|
44
|
+
|
|
45
|
+
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
46
|
+
let offset = 0;
|
|
47
|
+
let recordCount = 0;
|
|
48
|
+
|
|
49
|
+
while (offset < fileBuffer.length) {
|
|
50
|
+
const chunk = fileBuffer.slice(offset, offset + chunkSize);
|
|
51
|
+
const chunkStr = chunk.toString('utf8');
|
|
52
|
+
|
|
53
|
+
// Process chunk line-by-line
|
|
54
|
+
const lines = chunkStr.split('\n');
|
|
55
|
+
|
|
56
|
+
for (const line of lines) {
|
|
57
|
+
if (line.trim()) {
|
|
58
|
+
await processRecord(line);
|
|
59
|
+
recordCount++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
offset += chunkSize;
|
|
64
|
+
|
|
65
|
+
// Log progress
|
|
66
|
+
if (recordCount % 10000 === 0) {
|
|
67
|
+
console.log(`Processed ${recordCount} records...`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`Total records: ${recordCount}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function processRecord(line: string): Promise<void> {
|
|
75
|
+
// Your processing logic
|
|
76
|
+
const data = JSON.parse(line);
|
|
77
|
+
// ... handle data
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Strategy 2: Download with Size Limit
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// SFTP supports maxSize option to prevent large downloads
|
|
85
|
+
async function safeDownload(sftp: SftpDataSource, path: string) {
|
|
86
|
+
try {
|
|
87
|
+
const content = await sftp.downloadFile(path, {
|
|
88
|
+
maxSize: 100 * 1024 * 1024 // 100 MB limit
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return content;
|
|
92
|
+
|
|
93
|
+
} catch (error: any) {
|
|
94
|
+
if (error.message.includes('exceeds maximum')) {
|
|
95
|
+
console.error(`File ${path} is too large (> 100MB)`);
|
|
96
|
+
// Handle oversized file (skip, split, etc.)
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Strategy 3: Line-by-Line Processing from Buffer
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
async function processCSVFromBuffer(content: string | Buffer) {
|
|
108
|
+
const text = typeof content === 'string' ? content : content.toString('utf8');
|
|
109
|
+
const lines = text.split('\n');
|
|
110
|
+
|
|
111
|
+
const results: any[] = [];
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < lines.length; i++) {
|
|
114
|
+
const line = lines[i].trim();
|
|
115
|
+
|
|
116
|
+
if (!line) continue; // Skip empty lines
|
|
117
|
+
|
|
118
|
+
const record = parseCSVLine(line);
|
|
119
|
+
results.push(record);
|
|
120
|
+
|
|
121
|
+
// Clear memory periodically
|
|
122
|
+
if (results.length >= 10000) {
|
|
123
|
+
await processBatch(results);
|
|
124
|
+
results.length = 0; // Clear array
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Process remaining records
|
|
129
|
+
if (results.length > 0) {
|
|
130
|
+
await processBatch(results);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function parseCSVLine(line: string): any {
|
|
135
|
+
const fields = line.split(',');
|
|
136
|
+
return {
|
|
137
|
+
sku: fields[0],
|
|
138
|
+
qty: parseInt(fields[1], 10),
|
|
139
|
+
location: fields[2]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function processBatch(records: any[]): Promise<void> {
|
|
144
|
+
console.log(`Processing batch of ${records.length} records...`);
|
|
145
|
+
// Your batch processing logic
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Batch File Processing
|
|
150
|
+
|
|
151
|
+
### Parallel Processing with Controlled Concurrency
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { S3DataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
155
|
+
|
|
156
|
+
async function processManyFilesInParallel(s3: S3DataSource, prefix: string) {
|
|
157
|
+
const files = await s3.listFiles({ prefix });
|
|
158
|
+
|
|
159
|
+
const concurrency = 10; // Process 10 files at once
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < files.length; i += concurrency) {
|
|
162
|
+
const batch = files.slice(i, i + concurrency);
|
|
163
|
+
|
|
164
|
+
await Promise.all(
|
|
165
|
+
batch.map(async (file) => {
|
|
166
|
+
try {
|
|
167
|
+
console.log(`Processing ${file.name}...`);
|
|
168
|
+
|
|
169
|
+
const content = await s3.downloadFile(file.name);
|
|
170
|
+
const result = await transformData(content);
|
|
171
|
+
|
|
172
|
+
// Upload result
|
|
173
|
+
await s3.uploadFile(
|
|
174
|
+
file.name.replace('incoming/', 'output/'),
|
|
175
|
+
JSON.stringify(result),
|
|
176
|
+
{ contentType: 'application/json' }
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// Archive original
|
|
180
|
+
await s3.moveFile(
|
|
181
|
+
file.name,
|
|
182
|
+
file.name.replace('incoming/', 'archive/'),
|
|
183
|
+
true // deleteSource
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
console.log(`✓ Completed ${file.name}`);
|
|
187
|
+
|
|
188
|
+
} catch (error: any) {
|
|
189
|
+
console.error(`✗ Failed ${file.name}:`, error.message);
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
console.log(`Completed batch ${Math.floor(i / concurrency) + 1}/${Math.ceil(files.length / concurrency)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function transformData(content: string): Promise<any> {
|
|
199
|
+
// Your transformation logic
|
|
200
|
+
return { processed: true, data: content };
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Sequential Processing for Memory-Constrained Environments
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
async function processFilesSequentially(s3: S3DataSource, prefix: string) {
|
|
208
|
+
const files = await s3.listFiles({ prefix });
|
|
209
|
+
|
|
210
|
+
let successCount = 0;
|
|
211
|
+
let failureCount = 0;
|
|
212
|
+
|
|
213
|
+
for (const file of files) {
|
|
214
|
+
try {
|
|
215
|
+
console.log(`Processing ${file.name}...`);
|
|
216
|
+
|
|
217
|
+
// Download and process one file at a time
|
|
218
|
+
const content = await s3.downloadFile(file.name);
|
|
219
|
+
await processFileContent(content, file.name);
|
|
220
|
+
|
|
221
|
+
// Move to archive
|
|
222
|
+
await s3.moveFile(
|
|
223
|
+
file.name,
|
|
224
|
+
file.name.replace('incoming/', 'archive/'),
|
|
225
|
+
true
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
successCount++;
|
|
229
|
+
|
|
230
|
+
// Force garbage collection hint (Node.js)
|
|
231
|
+
if (global.gc) {
|
|
232
|
+
global.gc();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
} catch (error: any) {
|
|
236
|
+
console.error(`Failed ${file.name}:`, error.message);
|
|
237
|
+
failureCount++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
console.log(`\nResults: ${successCount} succeeded, ${failureCount} failed`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function processFileContent(content: string, fileName: string): Promise<void> {
|
|
245
|
+
// Process content line by line to manage memory
|
|
246
|
+
const lines = content.split('\n');
|
|
247
|
+
console.log(` Processing ${lines.length} lines...`);
|
|
248
|
+
|
|
249
|
+
for (const line of lines) {
|
|
250
|
+
if (line.trim()) {
|
|
251
|
+
// Process each line
|
|
252
|
+
await handleLine(line);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function handleLine(line: string): Promise<void> {
|
|
258
|
+
// Your line processing logic
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## SFTP Connection Pooling
|
|
263
|
+
|
|
264
|
+
### Reuse Connections for Better Performance
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { SftpDataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
268
|
+
|
|
269
|
+
// ✅ GOOD: Reuse connection for multiple operations
|
|
270
|
+
async function processMultipleFilesSftpReuse(config: any, logger: any) {
|
|
271
|
+
const sftp = new SftpDataSource(config, logger);
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
const files = await sftp.listFiles({ remotePath: '/incoming' });
|
|
275
|
+
|
|
276
|
+
for (const file of files) {
|
|
277
|
+
const content = await sftp.downloadFile(file.path);
|
|
278
|
+
await processData(content);
|
|
279
|
+
|
|
280
|
+
// Move to processed folder
|
|
281
|
+
await sftp.moveFile(
|
|
282
|
+
file.path,
|
|
283
|
+
file.path.replace('/incoming/', '/processed/'),
|
|
284
|
+
false // Don't overwrite
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
} finally {
|
|
289
|
+
await sftp.dispose(); // Close connection once
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ❌ BAD: Create new connection for each file
|
|
294
|
+
async function processMultipleFilesSftpSlow(config: any, logger: any, files: any[]) {
|
|
295
|
+
for (const file of files) {
|
|
296
|
+
const sftp = new SftpDataSource(config, logger);
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
const content = await sftp.downloadFile(file.path);
|
|
300
|
+
await processData(content);
|
|
301
|
+
} finally {
|
|
302
|
+
await sftp.dispose(); // Expensive connection overhead!
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async function processData(content: string | Buffer): Promise<void> {
|
|
308
|
+
// Your processing logic
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Performance Monitoring
|
|
313
|
+
|
|
314
|
+
### Track Processing Metrics
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
interface ProcessingMetrics {
|
|
318
|
+
filesProcessed: number;
|
|
319
|
+
filesSkipped: number;
|
|
320
|
+
filesFailed: number;
|
|
321
|
+
totalBytes: number;
|
|
322
|
+
totalRecords: number;
|
|
323
|
+
startTime: number;
|
|
324
|
+
endTime?: number;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async function processWithMetrics(s3: S3DataSource, prefix: string) {
|
|
328
|
+
const metrics: ProcessingMetrics = {
|
|
329
|
+
filesProcessed: 0,
|
|
330
|
+
filesSkipped: 0,
|
|
331
|
+
filesFailed: 0,
|
|
332
|
+
totalBytes: 0,
|
|
333
|
+
totalRecords: 0,
|
|
334
|
+
startTime: Date.now()
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const files = await s3.listFiles({ prefix });
|
|
338
|
+
console.log(`Found ${files.length} files to process\n`);
|
|
339
|
+
|
|
340
|
+
for (const file of files) {
|
|
341
|
+
try {
|
|
342
|
+
// Skip non-CSV files
|
|
343
|
+
if (!file.name.endsWith('.csv')) {
|
|
344
|
+
metrics.filesSkipped++;
|
|
345
|
+
console.log(`⊘ Skipped ${file.name} (not CSV)`);
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const content = await s3.downloadFile(file.name);
|
|
350
|
+
metrics.totalBytes += content.length;
|
|
351
|
+
|
|
352
|
+
const lines = content.split('\n').filter(l => l.trim());
|
|
353
|
+
metrics.totalRecords += lines.length;
|
|
354
|
+
|
|
355
|
+
await processFileData(content);
|
|
356
|
+
|
|
357
|
+
metrics.filesProcessed++;
|
|
358
|
+
console.log(`✓ Processed ${file.name} (${lines.length} records)`);
|
|
359
|
+
|
|
360
|
+
} catch (error: any) {
|
|
361
|
+
metrics.filesFailed++;
|
|
362
|
+
console.error(`✗ Failed ${file.name}:`, error.message);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
metrics.endTime = Date.now();
|
|
367
|
+
printMetrics(metrics);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function printMetrics(metrics: ProcessingMetrics): void {
|
|
371
|
+
const duration = ((metrics.endTime! - metrics.startTime) / 1000).toFixed(2);
|
|
372
|
+
const throughputMBps = (metrics.totalBytes / (1024 * 1024) / parseFloat(duration)).toFixed(2);
|
|
373
|
+
const throughputRecSec = (metrics.totalRecords / parseFloat(duration)).toFixed(0);
|
|
374
|
+
|
|
375
|
+
console.log('\n' + '='.repeat(50));
|
|
376
|
+
console.log('Processing Metrics:');
|
|
377
|
+
console.log('='.repeat(50));
|
|
378
|
+
console.log(`Files Processed: ${metrics.filesProcessed}`);
|
|
379
|
+
console.log(`Files Skipped: ${metrics.filesSkipped}`);
|
|
380
|
+
console.log(`Files Failed: ${metrics.filesFailed}`);
|
|
381
|
+
console.log(`Total Records: ${metrics.totalRecords}`);
|
|
382
|
+
console.log(`Total Data: ${(metrics.totalBytes / (1024 * 1024)).toFixed(2)} MB`);
|
|
383
|
+
console.log(`Duration: ${duration}s`);
|
|
384
|
+
console.log(`Throughput: ${throughputMBps} MB/s`);
|
|
385
|
+
console.log(`Records/Second: ${throughputRecSec}`);
|
|
386
|
+
console.log('='.repeat(50) + '\n');
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function processFileData(content: string): Promise<void> {
|
|
390
|
+
// Your processing logic
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Memory Management Tips
|
|
395
|
+
|
|
396
|
+
### 1. Use Binary Mode for Large Files
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
// For large files, use Buffer to avoid string conversion overhead
|
|
400
|
+
// S3: use encoding: 'binary'
|
|
401
|
+
const buffer = await s3.downloadFile(key, { encoding: 'binary' });
|
|
402
|
+
|
|
403
|
+
// SFTP: use asBuffer: true
|
|
404
|
+
const buffer = await sftp.downloadFile(path, { asBuffer: true });
|
|
405
|
+
|
|
406
|
+
// Process buffer directly
|
|
407
|
+
processBuffer(buffer);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### 2. Clear Large Arrays Periodically
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
const results: any[] = [];
|
|
414
|
+
|
|
415
|
+
for (const record of records) {
|
|
416
|
+
results.push(transformRecord(record));
|
|
417
|
+
|
|
418
|
+
// Clear memory every 10,000 records
|
|
419
|
+
if (results.length >= 10000) {
|
|
420
|
+
await writeToDestination(results);
|
|
421
|
+
results.length = 0; // Clear array to free memory
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### 3. Process Files in Batches
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// Instead of loading all files at once:
|
|
430
|
+
const files = await s3.listFiles({ prefix: 'data/' });
|
|
431
|
+
|
|
432
|
+
// Process in batches of 100
|
|
433
|
+
for (let i = 0; i < files.length; i += 100) {
|
|
434
|
+
const batch = files.slice(i, i + 100);
|
|
435
|
+
await Promise.all(batch.map(f => processFile(f)));
|
|
436
|
+
|
|
437
|
+
// Give GC a chance to run
|
|
438
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### 4. Use Deno/Versori Buffer Import
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// CRITICAL for Deno/Versori runtime
|
|
446
|
+
import { Buffer } from 'node:buffer';
|
|
447
|
+
|
|
448
|
+
const buffer = Buffer.from(content, 'utf8');
|
|
449
|
+
// ... use buffer
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Performance Comparison
|
|
453
|
+
|
|
454
|
+
### Download Methods
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
// Small files (< 10 MB): Direct string download
|
|
458
|
+
const content = await s3.downloadFile('small.csv'); // Fast
|
|
459
|
+
const lines = content.split('\n');
|
|
460
|
+
|
|
461
|
+
// Large files (> 10 MB): Binary download + chunk processing
|
|
462
|
+
const buffer = await s3.downloadFile('large.csv', { encoding: 'binary' });
|
|
463
|
+
processInChunks(buffer, 1024 * 1024); // 1 MB chunks
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Parallel vs Sequential
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Parallel (fast, high memory)
|
|
470
|
+
await Promise.all(files.map(f => processFile(f)));
|
|
471
|
+
|
|
472
|
+
// Sequential (slow, low memory)
|
|
473
|
+
for (const file of files) {
|
|
474
|
+
await processFile(file);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Batched parallel (balanced)
|
|
478
|
+
for (let i = 0; i < files.length; i += 10) {
|
|
479
|
+
await Promise.all(files.slice(i, i + 10).map(f => processFile(f)));
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## Key Takeaways
|
|
484
|
+
|
|
485
|
+
- 🎯 SDK does not provide built-in streaming - use download + chunk processing
|
|
486
|
+
- 🎯 Use `encoding: 'binary'` (S3) or `asBuffer: true` (SFTP) for large files to avoid string conversion overhead
|
|
487
|
+
- 🎯 Process files in chunks to maintain constant memory usage
|
|
488
|
+
- 🎯 Use parallel processing with controlled batch sizes (10-20 files at once)
|
|
489
|
+
- 🎯 Reuse SFTP connections for multiple operations
|
|
490
|
+
- 🎯 Monitor metrics to identify bottlenecks
|
|
491
|
+
- 🎯 Clear large arrays periodically to prevent memory buildup
|
|
492
|
+
- 🎯 Use `maxSize` option in SFTP to prevent downloading oversized files
|
|
493
|
+
|
|
494
|
+
## Next Steps
|
|
495
|
+
|
|
496
|
+
Continue to [Module 6: Archive Patterns](./file-operations-06-archive-patterns.md) for advanced archiving workflows.
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
**Related Resources:**
|
|
501
|
+
- [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md) - Performance tips
|
|
502
|
+
- [Module 7: Testing & Troubleshooting](./file-operations-07-testing-troubleshooting.md) - Memory issues
|
|
503
|
+
- [Common Patterns](../examples/common-patterns.ts) - Copy-paste ready snippets
|