@fluentcommerce/fc-connect-sdk 0.1.54 ā 0.1.56
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/README.md +11 -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
|
@@ -1,525 +1,525 @@
|
|
|
1
|
-
# Module 7: Performance Optimization
|
|
2
|
-
|
|
3
|
-
[ā Back to Parquet Guide](../parquet-readme.md)
|
|
4
|
-
|
|
5
|
-
**Module 7 of 8** | **Level**: Advanced | **Time**: 25 minutes
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
Learn advanced performance optimization techniques for processing large-scale Parquet datasets efficiently.
|
|
12
|
-
|
|
13
|
-
## Learning Objectives
|
|
14
|
-
|
|
15
|
-
By the end of this module, you will:
|
|
16
|
-
- ā
Optimize batch sizes for different file sizes
|
|
17
|
-
- ā
Implement parallel processing strategies
|
|
18
|
-
- ā
Use partitioning for efficient queries
|
|
19
|
-
- ā
Monitor and track performance metrics
|
|
20
|
-
- ā
Tune compression and row group settings
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Performance Benchmarks
|
|
25
|
-
|
|
26
|
-
### SDK Parser Performance
|
|
27
|
-
|
|
28
|
-
Based on test files in `fc-connect-sdk/tests/fixtures/parquet/`:
|
|
29
|
-
|
|
30
|
-
| File Size | Records | Processing Time | Throughput | Memory Usage |
|
|
31
|
-
|-----------|---------|-----------------|------------|--------------|
|
|
32
|
-
| **10 KB** | 50 | < 10 ms | 5,000+ rec/sec | ~10 MB |
|
|
33
|
-
| **170 KB** | 1,000 | 50-100 ms | 20,000 rec/sec | ~20 MB |
|
|
34
|
-
| **1.7 MB** | 10,000 | 200-300 ms | 35,000 rec/sec | ~30 MB |
|
|
35
|
-
| **8.5 MB** | 50,000 | 800ms-1s | 50,000 rec/sec | ~50 MB |
|
|
36
|
-
| **17 MB** | 100,000 | 1.5-2 sec | 55,000 rec/sec | ~70 MB |
|
|
37
|
-
| **85 MB** | 500,000 | 6-8 sec | 65,000 rec/sec | ~150 MB |
|
|
38
|
-
| **169 MB** | 1,000,000 | 12-15 sec | 70,000 rec/sec | ~200 MB |
|
|
39
|
-
|
|
40
|
-
**Hardware**: Node.js runtime, 8GB RAM, standard SSD
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Batch Size Optimization
|
|
45
|
-
|
|
46
|
-
### Choosing the Right Batch Size
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
/**
|
|
50
|
-
* Dynamic batch size based on file size
|
|
51
|
-
*/
|
|
52
|
-
function getOptimalBatchSize(fileSizeBytes: number): number {
|
|
53
|
-
const sizeMB = fileSizeBytes / 1024 / 1024;
|
|
54
|
-
|
|
55
|
-
if (sizeMB < 1) {
|
|
56
|
-
return 5000; // Small files: larger batches
|
|
57
|
-
} else if (sizeMB < 10) {
|
|
58
|
-
return 2000; // Medium files: balanced
|
|
59
|
-
} else if (sizeMB < 50) {
|
|
60
|
-
return 1000; // Large files: standard
|
|
61
|
-
} else {
|
|
62
|
-
return 500; // Very large files: smaller batches
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function parseWithOptimalBatchSize(
|
|
67
|
-
arrayBuffer: ArrayBuffer,
|
|
68
|
-
fileName: string,
|
|
69
|
-
fileSizeBytes: number
|
|
70
|
-
) {
|
|
71
|
-
const batchSize = getOptimalBatchSize(fileSizeBytes);
|
|
72
|
-
|
|
73
|
-
const parser = new ParquetParserService(logger, {
|
|
74
|
-
batchSize,
|
|
75
|
-
enableStreaming: fileSizeBytes > 50 * 1024 * 1024 // Stream if > 50MB
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
console.log(`Using batch size: ${batchSize}`);
|
|
79
|
-
|
|
80
|
-
if (parser.enableStreaming) {
|
|
81
|
-
const streamResult = await parser.parseStreaming(arrayBuffer, fileName);
|
|
82
|
-
|
|
83
|
-
for await (const batch of streamResult.records) {
|
|
84
|
-
await processBatch(batch);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return await streamResult.stats;
|
|
88
|
-
} else {
|
|
89
|
-
return await parser.parse(arrayBuffer, fileName);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## Parallel Processing
|
|
97
|
-
|
|
98
|
-
### Process Multiple Files Concurrently
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
/**
|
|
102
|
-
* Process multiple Parquet files in parallel
|
|
103
|
-
* Business use case: Batch processing of daily extracts
|
|
104
|
-
*/
|
|
105
|
-
class ParallelParquetProcessor {
|
|
106
|
-
private parser: ParquetParserService;
|
|
107
|
-
private concurrency: number;
|
|
108
|
-
|
|
109
|
-
constructor(concurrency: number = 3) {
|
|
110
|
-
this.parser = new ParquetParserService(logger, {
|
|
111
|
-
batchSize: 2000,
|
|
112
|
-
enableStreaming: true
|
|
113
|
-
});
|
|
114
|
-
this.concurrency = concurrency;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async processFiles(
|
|
118
|
-
files: Array<{ bucket: string; key: string }>
|
|
119
|
-
): Promise<void> {
|
|
120
|
-
const queue = [...files];
|
|
121
|
-
const workers: Promise<void>[] = [];
|
|
122
|
-
|
|
123
|
-
console.log(`Processing ${files.length} files with ${this.concurrency} workers`);
|
|
124
|
-
|
|
125
|
-
// Start workers
|
|
126
|
-
for (let i = 0; i < this.concurrency; i++) {
|
|
127
|
-
workers.push(this.worker(queue, i + 1));
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Wait for all workers to complete
|
|
131
|
-
await Promise.all(workers);
|
|
132
|
-
|
|
133
|
-
// Get final metrics
|
|
134
|
-
const metrics = this.parser.getPerformanceMetrics();
|
|
135
|
-
console.log(`\nā
Batch processing complete:`);
|
|
136
|
-
console.log(` Total files: ${files.length}`);
|
|
137
|
-
console.log(` Success rate: ${(metrics.successfulRequests / metrics.totalRequests * 100).toFixed(2)}%`);
|
|
138
|
-
console.log(` Avg processing time: ${metrics.averageResponseTime.toFixed(2)}ms`);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
private async worker(
|
|
142
|
-
queue: Array<{ bucket: string; key: string }>,
|
|
143
|
-
workerId: number
|
|
144
|
-
): Promise<void> {
|
|
145
|
-
while (queue.length > 0) {
|
|
146
|
-
const file = queue.shift();
|
|
147
|
-
if (!file) break;
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
console.log(`[Worker ${workerId}] Processing ${file.key}...`);
|
|
151
|
-
|
|
152
|
-
const buffer = await s3.downloadFile(file.key, { encoding: 'binary' });
|
|
153
|
-
const arrayBuffer = buffer.buffer.slice(
|
|
154
|
-
buffer.byteOffset,
|
|
155
|
-
buffer.byteOffset + buffer.byteLength
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
const startTime = Date.now();
|
|
159
|
-
const streamResult = await this.parser.parseStreaming(
|
|
160
|
-
arrayBuffer,
|
|
161
|
-
file.key,
|
|
162
|
-
{ batchSize: 5000 }
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
for await (const batch of streamResult.records) {
|
|
166
|
-
await this.processBatch(batch);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const stats = await streamResult.stats;
|
|
170
|
-
const duration = Date.now() - startTime;
|
|
171
|
-
|
|
172
|
-
console.log(`[Worker ${workerId}] ā
${file.key}: ${stats.totalRecords} records in ${duration}ms`);
|
|
173
|
-
|
|
174
|
-
} catch (error) {
|
|
175
|
-
console.error(`[Worker ${workerId}] ā Failed ${file.key}:`, error.message);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
console.log(`[Worker ${workerId}] Finished`);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
private async processBatch(batch: any[]): Promise<void> {
|
|
183
|
-
// Your processing logic
|
|
184
|
-
// Parallel batch processing within each worker
|
|
185
|
-
await Promise.all(
|
|
186
|
-
batch.map(record => this.processRecord(record))
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
private async processRecord(record: any): Promise<void> {
|
|
191
|
-
// Your business logic
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Usage
|
|
196
|
-
const processor = new ParallelParquetProcessor(3); // 3 concurrent workers
|
|
197
|
-
await processor.processFiles([
|
|
198
|
-
{ bucket: 'data-lake', key: 'inventory/2025-10-18.parquet' },
|
|
199
|
-
{ bucket: 'data-lake', key: 'inventory/2025-10-19.parquet' },
|
|
200
|
-
{ bucket: 'data-lake', key: 'inventory/2025-10-20.parquet' }
|
|
201
|
-
]);
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## Partitioning Strategies
|
|
207
|
-
|
|
208
|
-
### Time-Based Partitioning
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Generate time-based partitions for efficient queries
|
|
215
|
-
* Business use case: Daily snapshots for analytics
|
|
216
|
-
*/
|
|
217
|
-
class PartitionedExtractor {
|
|
218
|
-
async extractWithTimePartitioning(
|
|
219
|
-
outputDir: string,
|
|
220
|
-
startDate: Date,
|
|
221
|
-
endDate: Date
|
|
222
|
-
): Promise<void> {
|
|
223
|
-
const dates = this.getDateRange(startDate, endDate);
|
|
224
|
-
|
|
225
|
-
for (const date of dates) {
|
|
226
|
-
// Hive-style partitioning: year=YYYY/month=MM/day=DD
|
|
227
|
-
const partition = `year=${date.year}/month=${date.month}/day=${date.day}`;
|
|
228
|
-
const outputPath = `${outputDir}/${partition}/data.parquet`;
|
|
229
|
-
|
|
230
|
-
console.log(`\nExtracting partition: ${partition}`);
|
|
231
|
-
|
|
232
|
-
const schema = new parquet.ParquetSchema({
|
|
233
|
-
ref: { type: 'UTF8' },
|
|
234
|
-
productRef: { type: 'UTF8' },
|
|
235
|
-
locationRef: { type: 'UTF8' },
|
|
236
|
-
qty: { type: 'INT32' },
|
|
237
|
-
updatedOn: { type: 'TIMESTAMP_MILLIS' }
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
const writer = await parquet.ParquetWriter.openFile(schema, outputPath, {
|
|
241
|
-
compression: 'SNAPPY',
|
|
242
|
-
rowGroupSize: 10000
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// Extract data for this partition
|
|
246
|
-
let hasNextPage = true;
|
|
247
|
-
let cursor: string | null = null;
|
|
248
|
-
let partitionRecords = 0;
|
|
249
|
-
|
|
250
|
-
while (hasNextPage) {
|
|
251
|
-
const result = await client.graphql({
|
|
252
|
-
query: `
|
|
253
|
-
query ExtractPartition($from: DateTime!, $to: DateTime!, $after: String, $first: Int!) {
|
|
254
|
-
inventoryPositions(
|
|
255
|
-
after: $after,
|
|
256
|
-
first: $first,
|
|
257
|
-
updatedOn: { from: $from, to: $to }
|
|
258
|
-
) {
|
|
259
|
-
pageInfo { hasNextPage }
|
|
260
|
-
edges {
|
|
261
|
-
cursor
|
|
262
|
-
node { ref productRef locationRef qty updatedOn }
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
`,
|
|
267
|
-
variables: {
|
|
268
|
-
from: date.start.toISOString(),
|
|
269
|
-
to: date.end.toISOString(),
|
|
270
|
-
first: 1000,
|
|
271
|
-
after: cursor
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
const { edges, pageInfo } = result.data.inventoryPositions;
|
|
276
|
-
|
|
277
|
-
for (const edge of edges) {
|
|
278
|
-
await writer.appendRow({
|
|
279
|
-
...edge.node,
|
|
280
|
-
updatedOn: edge.node.updatedOn ? new Date(edge.node.updatedOn) : null
|
|
281
|
-
});
|
|
282
|
-
partitionRecords++;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
hasNextPage = pageInfo.hasNextPage;
|
|
286
|
-
cursor = edges.length > 0 ? edges[edges.length - 1].cursor : null;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
await writer.close();
|
|
290
|
-
console.log(`ā
${partition}: ${partitionRecords} records`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
private getDateRange(start: Date, end: Date): any[] {
|
|
295
|
-
const dates = [];
|
|
296
|
-
const current = new Date(start);
|
|
297
|
-
|
|
298
|
-
while (current <= end) {
|
|
299
|
-
dates.push({
|
|
300
|
-
year: current.getFullYear(),
|
|
301
|
-
month: String(current.getMonth() + 1).padStart(2, '0'),
|
|
302
|
-
day: String(current.getDate()).padStart(2, '0'),
|
|
303
|
-
start: new Date(current.setHours(0, 0, 0, 0)),
|
|
304
|
-
end: new Date(current.setHours(23, 59, 59, 999))
|
|
305
|
-
});
|
|
306
|
-
current.setDate(current.getDate() + 1);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
return dates;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Category-Based Partitioning
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Partition by business category
|
|
321
|
-
* Business use case: Separate high-value vs low-value inventory
|
|
322
|
-
*/
|
|
323
|
-
async function extractWithCategoryPartitioning(outputDir: string): Promise<void> {
|
|
324
|
-
const categories = [
|
|
325
|
-
{ name: 'high-value', filter: { minQty: 1000 } },
|
|
326
|
-
{ name: 'medium-value', filter: { minQty: 100, maxQty: 999 } },
|
|
327
|
-
{ name: 'low-value', filter: { maxQty: 99 } }
|
|
328
|
-
];
|
|
329
|
-
|
|
330
|
-
for (const category of categories) {
|
|
331
|
-
const outputPath = `${outputDir}/category=${category.name}/data.parquet`;
|
|
332
|
-
console.log(`Extracting category: ${category.name}`);
|
|
333
|
-
|
|
334
|
-
// Extract and write for this category
|
|
335
|
-
// (Implementation similar to time-based partitioning)
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## Compression Optimization
|
|
343
|
-
|
|
344
|
-
### Compression Trade-offs
|
|
345
|
-
|
|
346
|
-
```typescript
|
|
347
|
-
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
348
|
-
import * as parquet from 'parquetjs';
|
|
349
|
-
import * as fs from 'fs/promises';
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Test different compression algorithms
|
|
353
|
-
*/
|
|
354
|
-
async function benchmarkCompression(
|
|
355
|
-
records: any[],
|
|
356
|
-
outputDir: string
|
|
357
|
-
): Promise<void> {
|
|
358
|
-
const compressions = ['UNCOMPRESSED', 'SNAPPY', 'GZIP', 'BROTLI'];
|
|
359
|
-
const results = [];
|
|
360
|
-
|
|
361
|
-
for (const compression of compressions) {
|
|
362
|
-
const outputFile = `${outputDir}/test_${compression.toLowerCase()}.parquet`;
|
|
363
|
-
|
|
364
|
-
const startTime = Date.now();
|
|
365
|
-
|
|
366
|
-
const writer = await parquet.ParquetWriter.openFile(schema, outputFile, {
|
|
367
|
-
compression: compression as any,
|
|
368
|
-
rowGroupSize: 10000
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
for (const record of records) {
|
|
372
|
-
await writer.appendRow(record);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
await writer.close();
|
|
376
|
-
|
|
377
|
-
const duration = Date.now() - startTime;
|
|
378
|
-
const fileStats = await fs.stat(outputFile);
|
|
379
|
-
|
|
380
|
-
results.push({
|
|
381
|
-
compression,
|
|
382
|
-
writeTime: duration,
|
|
383
|
-
fileSize: fileStats.size,
|
|
384
|
-
fileSizeMB: (fileStats.size / 1024 / 1024).toFixed(2)
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
console.log(`${compression}: ${duration}ms, ${(fileStats.size / 1024 / 1024).toFixed(2)}MB`);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
console.table(results);
|
|
391
|
-
}
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
**Typical Results** (100K records):
|
|
395
|
-
|
|
396
|
-
| Compression | Write Time | File Size | Compression Ratio |
|
|
397
|
-
|-------------|------------|-----------|-------------------|
|
|
398
|
-
| UNCOMPRESSED | 1.2 sec | 20 MB | 1x |
|
|
399
|
-
| SNAPPY | 1.5 sec | 7 MB | 2.9x |
|
|
400
|
-
| GZIP | 3.2 sec | 5 MB | 4x |
|
|
401
|
-
| BROTLI | 8.5 sec | 4 MB | 5x |
|
|
402
|
-
|
|
403
|
-
---
|
|
404
|
-
|
|
405
|
-
## Memory Management
|
|
406
|
-
|
|
407
|
-
### Garbage Collection Hints
|
|
408
|
-
|
|
409
|
-
```typescript
|
|
410
|
-
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Process with explicit memory management
|
|
414
|
-
*/
|
|
415
|
-
async function processWithMemoryManagement(
|
|
416
|
-
arrayBuffer: ArrayBuffer,
|
|
417
|
-
fileName: string
|
|
418
|
-
): Promise<void> {
|
|
419
|
-
const parser = new ParquetParserService(logger, {
|
|
420
|
-
batchSize: 500, // Small batches
|
|
421
|
-
enableStreaming: true
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
const streamResult = await parser.parseStreaming(arrayBuffer, fileName);
|
|
425
|
-
|
|
426
|
-
let processedCount = 0;
|
|
427
|
-
|
|
428
|
-
for await (const batch of streamResult.records) {
|
|
429
|
-
// Process batch
|
|
430
|
-
await processBatch(batch);
|
|
431
|
-
|
|
432
|
-
processedCount += batch.length;
|
|
433
|
-
|
|
434
|
-
// Periodic GC hint
|
|
435
|
-
if (processedCount % 50000 === 0) {
|
|
436
|
-
console.log(`Processed ${processedCount} records`);
|
|
437
|
-
|
|
438
|
-
// Force GC if available (run with --expose-gc)
|
|
439
|
-
if (global.gc) {
|
|
440
|
-
global.gc();
|
|
441
|
-
const mem = process.memoryUsage();
|
|
442
|
-
console.log(` Heap: ${(mem.heapUsed / 1024 / 1024).toFixed(2)}MB`);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
const stats = await streamResult.stats;
|
|
448
|
-
console.log(`Peak memory: ${(stats.peakMemoryUsage / 1024 / 1024).toFixed(2)}MB`);
|
|
449
|
-
}
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
---
|
|
453
|
-
|
|
454
|
-
## Performance Monitoring
|
|
455
|
-
|
|
456
|
-
### Comprehensive Metrics
|
|
457
|
-
|
|
458
|
-
```typescript
|
|
459
|
-
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
460
|
-
|
|
461
|
-
class PerformanceTracker {
|
|
462
|
-
private startTime: number;
|
|
463
|
-
private checkpoints: Map<string, number>;
|
|
464
|
-
|
|
465
|
-
constructor() {
|
|
466
|
-
this.startTime = Date.now();
|
|
467
|
-
this.checkpoints = new Map();
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
checkpoint(name: string): void {
|
|
471
|
-
this.checkpoints.set(name, Date.now() - this.startTime);
|
|
472
|
-
console.log(`ā ${name}: ${this.checkpoints.get(name)}ms`);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
summary(): void {
|
|
476
|
-
console.log('\nš Performance Summary:');
|
|
477
|
-
for (const [name, duration] of this.checkpoints) {
|
|
478
|
-
console.log(` ${name}: ${duration}ms`);
|
|
479
|
-
}
|
|
480
|
-
console.log(` Total: ${Date.now() - this.startTime}ms`);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Usage
|
|
485
|
-
const tracker = new PerformanceTracker();
|
|
486
|
-
|
|
487
|
-
tracker.checkpoint('Download from S3');
|
|
488
|
-
// ... download code
|
|
489
|
-
|
|
490
|
-
tracker.checkpoint('Parse Parquet');
|
|
491
|
-
// ... parsing code
|
|
492
|
-
|
|
493
|
-
tracker.checkpoint('Transform data');
|
|
494
|
-
// ... transformation code
|
|
495
|
-
|
|
496
|
-
tracker.checkpoint('Upload to target');
|
|
497
|
-
// ... upload code
|
|
498
|
-
|
|
499
|
-
tracker.summary();
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
---
|
|
503
|
-
|
|
504
|
-
## Key Takeaways
|
|
505
|
-
|
|
506
|
-
- šÆ **Dynamic batch sizes** - Adjust based on file size
|
|
507
|
-
- šÆ **Parallel processing** - Use worker pools for multiple files
|
|
508
|
-
- šÆ **Partitioning** - Time/category-based for efficient queries
|
|
509
|
-
- šÆ **SNAPPY compression** - Best balance for most cases
|
|
510
|
-
- šÆ **Monitor metrics** - Track and optimize performance
|
|
511
|
-
|
|
512
|
-
---
|
|
513
|
-
|
|
514
|
-
## Next Steps
|
|
515
|
-
|
|
516
|
-
Continue to [Module 8: Best Practices](./03-pattern-guides-parquet-08-best-practices.md) to learn production patterns, error handling, and troubleshooting.
|
|
517
|
-
|
|
518
|
-
---
|
|
519
|
-
|
|
520
|
-
[ā Previous: Module 6 - S3 Integration](./03-pattern-guides-parquet-06-s3-integration.md) | [Back to Guide](../parquet-readme.md) | [Next: Module 8 - Best Practices ā](./03-pattern-guides-parquet-08-best-practices.md)
|
|
521
|
-
|
|
522
|
-
## Related Documentation
|
|
523
|
-
|
|
524
|
-
- [Module 3: Reading Parquet](./03-pattern-guides-parquet-03-reading-parquet.md) - Streaming and validation
|
|
525
|
-
- [Module 8: Best Practices](./03-pattern-guides-parquet-08-best-practices.md) - Production patterns
|
|
1
|
+
# Module 7: Performance Optimization
|
|
2
|
+
|
|
3
|
+
[ā Back to Parquet Guide](../parquet-readme.md)
|
|
4
|
+
|
|
5
|
+
**Module 7 of 8** | **Level**: Advanced | **Time**: 25 minutes
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Learn advanced performance optimization techniques for processing large-scale Parquet datasets efficiently.
|
|
12
|
+
|
|
13
|
+
## Learning Objectives
|
|
14
|
+
|
|
15
|
+
By the end of this module, you will:
|
|
16
|
+
- ā
Optimize batch sizes for different file sizes
|
|
17
|
+
- ā
Implement parallel processing strategies
|
|
18
|
+
- ā
Use partitioning for efficient queries
|
|
19
|
+
- ā
Monitor and track performance metrics
|
|
20
|
+
- ā
Tune compression and row group settings
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Performance Benchmarks
|
|
25
|
+
|
|
26
|
+
### SDK Parser Performance
|
|
27
|
+
|
|
28
|
+
Based on test files in `fc-connect-sdk/tests/fixtures/parquet/`:
|
|
29
|
+
|
|
30
|
+
| File Size | Records | Processing Time | Throughput | Memory Usage |
|
|
31
|
+
|-----------|---------|-----------------|------------|--------------|
|
|
32
|
+
| **10 KB** | 50 | < 10 ms | 5,000+ rec/sec | ~10 MB |
|
|
33
|
+
| **170 KB** | 1,000 | 50-100 ms | 20,000 rec/sec | ~20 MB |
|
|
34
|
+
| **1.7 MB** | 10,000 | 200-300 ms | 35,000 rec/sec | ~30 MB |
|
|
35
|
+
| **8.5 MB** | 50,000 | 800ms-1s | 50,000 rec/sec | ~50 MB |
|
|
36
|
+
| **17 MB** | 100,000 | 1.5-2 sec | 55,000 rec/sec | ~70 MB |
|
|
37
|
+
| **85 MB** | 500,000 | 6-8 sec | 65,000 rec/sec | ~150 MB |
|
|
38
|
+
| **169 MB** | 1,000,000 | 12-15 sec | 70,000 rec/sec | ~200 MB |
|
|
39
|
+
|
|
40
|
+
**Hardware**: Node.js runtime, 8GB RAM, standard SSD
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Batch Size Optimization
|
|
45
|
+
|
|
46
|
+
### Choosing the Right Batch Size
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
/**
|
|
50
|
+
* Dynamic batch size based on file size
|
|
51
|
+
*/
|
|
52
|
+
function getOptimalBatchSize(fileSizeBytes: number): number {
|
|
53
|
+
const sizeMB = fileSizeBytes / 1024 / 1024;
|
|
54
|
+
|
|
55
|
+
if (sizeMB < 1) {
|
|
56
|
+
return 5000; // Small files: larger batches
|
|
57
|
+
} else if (sizeMB < 10) {
|
|
58
|
+
return 2000; // Medium files: balanced
|
|
59
|
+
} else if (sizeMB < 50) {
|
|
60
|
+
return 1000; // Large files: standard
|
|
61
|
+
} else {
|
|
62
|
+
return 500; // Very large files: smaller batches
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function parseWithOptimalBatchSize(
|
|
67
|
+
arrayBuffer: ArrayBuffer,
|
|
68
|
+
fileName: string,
|
|
69
|
+
fileSizeBytes: number
|
|
70
|
+
) {
|
|
71
|
+
const batchSize = getOptimalBatchSize(fileSizeBytes);
|
|
72
|
+
|
|
73
|
+
const parser = new ParquetParserService(logger, {
|
|
74
|
+
batchSize,
|
|
75
|
+
enableStreaming: fileSizeBytes > 50 * 1024 * 1024 // Stream if > 50MB
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
console.log(`Using batch size: ${batchSize}`);
|
|
79
|
+
|
|
80
|
+
if (parser.enableStreaming) {
|
|
81
|
+
const streamResult = await parser.parseStreaming(arrayBuffer, fileName);
|
|
82
|
+
|
|
83
|
+
for await (const batch of streamResult.records) {
|
|
84
|
+
await processBatch(batch);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return await streamResult.stats;
|
|
88
|
+
} else {
|
|
89
|
+
return await parser.parse(arrayBuffer, fileName);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Parallel Processing
|
|
97
|
+
|
|
98
|
+
### Process Multiple Files Concurrently
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
/**
|
|
102
|
+
* Process multiple Parquet files in parallel
|
|
103
|
+
* Business use case: Batch processing of daily extracts
|
|
104
|
+
*/
|
|
105
|
+
class ParallelParquetProcessor {
|
|
106
|
+
private parser: ParquetParserService;
|
|
107
|
+
private concurrency: number;
|
|
108
|
+
|
|
109
|
+
constructor(concurrency: number = 3) {
|
|
110
|
+
this.parser = new ParquetParserService(logger, {
|
|
111
|
+
batchSize: 2000,
|
|
112
|
+
enableStreaming: true
|
|
113
|
+
});
|
|
114
|
+
this.concurrency = concurrency;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async processFiles(
|
|
118
|
+
files: Array<{ bucket: string; key: string }>
|
|
119
|
+
): Promise<void> {
|
|
120
|
+
const queue = [...files];
|
|
121
|
+
const workers: Promise<void>[] = [];
|
|
122
|
+
|
|
123
|
+
console.log(`Processing ${files.length} files with ${this.concurrency} workers`);
|
|
124
|
+
|
|
125
|
+
// Start workers
|
|
126
|
+
for (let i = 0; i < this.concurrency; i++) {
|
|
127
|
+
workers.push(this.worker(queue, i + 1));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Wait for all workers to complete
|
|
131
|
+
await Promise.all(workers);
|
|
132
|
+
|
|
133
|
+
// Get final metrics
|
|
134
|
+
const metrics = this.parser.getPerformanceMetrics();
|
|
135
|
+
console.log(`\nā
Batch processing complete:`);
|
|
136
|
+
console.log(` Total files: ${files.length}`);
|
|
137
|
+
console.log(` Success rate: ${(metrics.successfulRequests / metrics.totalRequests * 100).toFixed(2)}%`);
|
|
138
|
+
console.log(` Avg processing time: ${metrics.averageResponseTime.toFixed(2)}ms`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private async worker(
|
|
142
|
+
queue: Array<{ bucket: string; key: string }>,
|
|
143
|
+
workerId: number
|
|
144
|
+
): Promise<void> {
|
|
145
|
+
while (queue.length > 0) {
|
|
146
|
+
const file = queue.shift();
|
|
147
|
+
if (!file) break;
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
console.log(`[Worker ${workerId}] Processing ${file.key}...`);
|
|
151
|
+
|
|
152
|
+
const buffer = await s3.downloadFile(file.key, { encoding: 'binary' });
|
|
153
|
+
const arrayBuffer = buffer.buffer.slice(
|
|
154
|
+
buffer.byteOffset,
|
|
155
|
+
buffer.byteOffset + buffer.byteLength
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const startTime = Date.now();
|
|
159
|
+
const streamResult = await this.parser.parseStreaming(
|
|
160
|
+
arrayBuffer,
|
|
161
|
+
file.key,
|
|
162
|
+
{ batchSize: 5000 }
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
for await (const batch of streamResult.records) {
|
|
166
|
+
await this.processBatch(batch);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const stats = await streamResult.stats;
|
|
170
|
+
const duration = Date.now() - startTime;
|
|
171
|
+
|
|
172
|
+
console.log(`[Worker ${workerId}] ā
${file.key}: ${stats.totalRecords} records in ${duration}ms`);
|
|
173
|
+
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(`[Worker ${workerId}] ā Failed ${file.key}:`, error.message);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log(`[Worker ${workerId}] Finished`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private async processBatch(batch: any[]): Promise<void> {
|
|
183
|
+
// Your processing logic
|
|
184
|
+
// Parallel batch processing within each worker
|
|
185
|
+
await Promise.all(
|
|
186
|
+
batch.map(record => this.processRecord(record))
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private async processRecord(record: any): Promise<void> {
|
|
191
|
+
// Your business logic
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Usage
|
|
196
|
+
const processor = new ParallelParquetProcessor(3); // 3 concurrent workers
|
|
197
|
+
await processor.processFiles([
|
|
198
|
+
{ bucket: 'data-lake', key: 'inventory/2025-10-18.parquet' },
|
|
199
|
+
{ bucket: 'data-lake', key: 'inventory/2025-10-19.parquet' },
|
|
200
|
+
{ bucket: 'data-lake', key: 'inventory/2025-10-20.parquet' }
|
|
201
|
+
]);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Partitioning Strategies
|
|
207
|
+
|
|
208
|
+
### Time-Based Partitioning
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Generate time-based partitions for efficient queries
|
|
215
|
+
* Business use case: Daily snapshots for analytics
|
|
216
|
+
*/
|
|
217
|
+
class PartitionedExtractor {
|
|
218
|
+
async extractWithTimePartitioning(
|
|
219
|
+
outputDir: string,
|
|
220
|
+
startDate: Date,
|
|
221
|
+
endDate: Date
|
|
222
|
+
): Promise<void> {
|
|
223
|
+
const dates = this.getDateRange(startDate, endDate);
|
|
224
|
+
|
|
225
|
+
for (const date of dates) {
|
|
226
|
+
// Hive-style partitioning: year=YYYY/month=MM/day=DD
|
|
227
|
+
const partition = `year=${date.year}/month=${date.month}/day=${date.day}`;
|
|
228
|
+
const outputPath = `${outputDir}/${partition}/data.parquet`;
|
|
229
|
+
|
|
230
|
+
console.log(`\nExtracting partition: ${partition}`);
|
|
231
|
+
|
|
232
|
+
const schema = new parquet.ParquetSchema({
|
|
233
|
+
ref: { type: 'UTF8' },
|
|
234
|
+
productRef: { type: 'UTF8' },
|
|
235
|
+
locationRef: { type: 'UTF8' },
|
|
236
|
+
qty: { type: 'INT32' },
|
|
237
|
+
updatedOn: { type: 'TIMESTAMP_MILLIS' }
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const writer = await parquet.ParquetWriter.openFile(schema, outputPath, {
|
|
241
|
+
compression: 'SNAPPY',
|
|
242
|
+
rowGroupSize: 10000
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Extract data for this partition
|
|
246
|
+
let hasNextPage = true;
|
|
247
|
+
let cursor: string | null = null;
|
|
248
|
+
let partitionRecords = 0;
|
|
249
|
+
|
|
250
|
+
while (hasNextPage) {
|
|
251
|
+
const result = await client.graphql({
|
|
252
|
+
query: `
|
|
253
|
+
query ExtractPartition($from: DateTime!, $to: DateTime!, $after: String, $first: Int!) {
|
|
254
|
+
inventoryPositions(
|
|
255
|
+
after: $after,
|
|
256
|
+
first: $first,
|
|
257
|
+
updatedOn: { from: $from, to: $to }
|
|
258
|
+
) {
|
|
259
|
+
pageInfo { hasNextPage }
|
|
260
|
+
edges {
|
|
261
|
+
cursor
|
|
262
|
+
node { ref productRef locationRef qty updatedOn }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
`,
|
|
267
|
+
variables: {
|
|
268
|
+
from: date.start.toISOString(),
|
|
269
|
+
to: date.end.toISOString(),
|
|
270
|
+
first: 1000,
|
|
271
|
+
after: cursor
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const { edges, pageInfo } = result.data.inventoryPositions;
|
|
276
|
+
|
|
277
|
+
for (const edge of edges) {
|
|
278
|
+
await writer.appendRow({
|
|
279
|
+
...edge.node,
|
|
280
|
+
updatedOn: edge.node.updatedOn ? new Date(edge.node.updatedOn) : null
|
|
281
|
+
});
|
|
282
|
+
partitionRecords++;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
hasNextPage = pageInfo.hasNextPage;
|
|
286
|
+
cursor = edges.length > 0 ? edges[edges.length - 1].cursor : null;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
await writer.close();
|
|
290
|
+
console.log(`ā
${partition}: ${partitionRecords} records`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private getDateRange(start: Date, end: Date): any[] {
|
|
295
|
+
const dates = [];
|
|
296
|
+
const current = new Date(start);
|
|
297
|
+
|
|
298
|
+
while (current <= end) {
|
|
299
|
+
dates.push({
|
|
300
|
+
year: current.getFullYear(),
|
|
301
|
+
month: String(current.getMonth() + 1).padStart(2, '0'),
|
|
302
|
+
day: String(current.getDate()).padStart(2, '0'),
|
|
303
|
+
start: new Date(current.setHours(0, 0, 0, 0)),
|
|
304
|
+
end: new Date(current.setHours(23, 59, 59, 999))
|
|
305
|
+
});
|
|
306
|
+
current.setDate(current.getDate() + 1);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return dates;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Category-Based Partitioning
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Partition by business category
|
|
321
|
+
* Business use case: Separate high-value vs low-value inventory
|
|
322
|
+
*/
|
|
323
|
+
async function extractWithCategoryPartitioning(outputDir: string): Promise<void> {
|
|
324
|
+
const categories = [
|
|
325
|
+
{ name: 'high-value', filter: { minQty: 1000 } },
|
|
326
|
+
{ name: 'medium-value', filter: { minQty: 100, maxQty: 999 } },
|
|
327
|
+
{ name: 'low-value', filter: { maxQty: 99 } }
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
for (const category of categories) {
|
|
331
|
+
const outputPath = `${outputDir}/category=${category.name}/data.parquet`;
|
|
332
|
+
console.log(`Extracting category: ${category.name}`);
|
|
333
|
+
|
|
334
|
+
// Extract and write for this category
|
|
335
|
+
// (Implementation similar to time-based partitioning)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Compression Optimization
|
|
343
|
+
|
|
344
|
+
### Compression Trade-offs
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
348
|
+
import * as parquet from 'parquetjs';
|
|
349
|
+
import * as fs from 'fs/promises';
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Test different compression algorithms
|
|
353
|
+
*/
|
|
354
|
+
async function benchmarkCompression(
|
|
355
|
+
records: any[],
|
|
356
|
+
outputDir: string
|
|
357
|
+
): Promise<void> {
|
|
358
|
+
const compressions = ['UNCOMPRESSED', 'SNAPPY', 'GZIP', 'BROTLI'];
|
|
359
|
+
const results = [];
|
|
360
|
+
|
|
361
|
+
for (const compression of compressions) {
|
|
362
|
+
const outputFile = `${outputDir}/test_${compression.toLowerCase()}.parquet`;
|
|
363
|
+
|
|
364
|
+
const startTime = Date.now();
|
|
365
|
+
|
|
366
|
+
const writer = await parquet.ParquetWriter.openFile(schema, outputFile, {
|
|
367
|
+
compression: compression as any,
|
|
368
|
+
rowGroupSize: 10000
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
for (const record of records) {
|
|
372
|
+
await writer.appendRow(record);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
await writer.close();
|
|
376
|
+
|
|
377
|
+
const duration = Date.now() - startTime;
|
|
378
|
+
const fileStats = await fs.stat(outputFile);
|
|
379
|
+
|
|
380
|
+
results.push({
|
|
381
|
+
compression,
|
|
382
|
+
writeTime: duration,
|
|
383
|
+
fileSize: fileStats.size,
|
|
384
|
+
fileSizeMB: (fileStats.size / 1024 / 1024).toFixed(2)
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
console.log(`${compression}: ${duration}ms, ${(fileStats.size / 1024 / 1024).toFixed(2)}MB`);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
console.table(results);
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Typical Results** (100K records):
|
|
395
|
+
|
|
396
|
+
| Compression | Write Time | File Size | Compression Ratio |
|
|
397
|
+
|-------------|------------|-----------|-------------------|
|
|
398
|
+
| UNCOMPRESSED | 1.2 sec | 20 MB | 1x |
|
|
399
|
+
| SNAPPY | 1.5 sec | 7 MB | 2.9x |
|
|
400
|
+
| GZIP | 3.2 sec | 5 MB | 4x |
|
|
401
|
+
| BROTLI | 8.5 sec | 4 MB | 5x |
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Memory Management
|
|
406
|
+
|
|
407
|
+
### Garbage Collection Hints
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Process with explicit memory management
|
|
414
|
+
*/
|
|
415
|
+
async function processWithMemoryManagement(
|
|
416
|
+
arrayBuffer: ArrayBuffer,
|
|
417
|
+
fileName: string
|
|
418
|
+
): Promise<void> {
|
|
419
|
+
const parser = new ParquetParserService(logger, {
|
|
420
|
+
batchSize: 500, // Small batches
|
|
421
|
+
enableStreaming: true
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
const streamResult = await parser.parseStreaming(arrayBuffer, fileName);
|
|
425
|
+
|
|
426
|
+
let processedCount = 0;
|
|
427
|
+
|
|
428
|
+
for await (const batch of streamResult.records) {
|
|
429
|
+
// Process batch
|
|
430
|
+
await processBatch(batch);
|
|
431
|
+
|
|
432
|
+
processedCount += batch.length;
|
|
433
|
+
|
|
434
|
+
// Periodic GC hint
|
|
435
|
+
if (processedCount % 50000 === 0) {
|
|
436
|
+
console.log(`Processed ${processedCount} records`);
|
|
437
|
+
|
|
438
|
+
// Force GC if available (run with --expose-gc)
|
|
439
|
+
if (global.gc) {
|
|
440
|
+
global.gc();
|
|
441
|
+
const mem = process.memoryUsage();
|
|
442
|
+
console.log(` Heap: ${(mem.heapUsed / 1024 / 1024).toFixed(2)}MB`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const stats = await streamResult.stats;
|
|
448
|
+
console.log(`Peak memory: ${(stats.peakMemoryUsage / 1024 / 1024).toFixed(2)}MB`);
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Performance Monitoring
|
|
455
|
+
|
|
456
|
+
### Comprehensive Metrics
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
import { Buffer } from 'node:buffer'; // Required for Deno/Versori
|
|
460
|
+
|
|
461
|
+
class PerformanceTracker {
|
|
462
|
+
private startTime: number;
|
|
463
|
+
private checkpoints: Map<string, number>;
|
|
464
|
+
|
|
465
|
+
constructor() {
|
|
466
|
+
this.startTime = Date.now();
|
|
467
|
+
this.checkpoints = new Map();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
checkpoint(name: string): void {
|
|
471
|
+
this.checkpoints.set(name, Date.now() - this.startTime);
|
|
472
|
+
console.log(`ā ${name}: ${this.checkpoints.get(name)}ms`);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
summary(): void {
|
|
476
|
+
console.log('\nš Performance Summary:');
|
|
477
|
+
for (const [name, duration] of this.checkpoints) {
|
|
478
|
+
console.log(` ${name}: ${duration}ms`);
|
|
479
|
+
}
|
|
480
|
+
console.log(` Total: ${Date.now() - this.startTime}ms`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Usage
|
|
485
|
+
const tracker = new PerformanceTracker();
|
|
486
|
+
|
|
487
|
+
tracker.checkpoint('Download from S3');
|
|
488
|
+
// ... download code
|
|
489
|
+
|
|
490
|
+
tracker.checkpoint('Parse Parquet');
|
|
491
|
+
// ... parsing code
|
|
492
|
+
|
|
493
|
+
tracker.checkpoint('Transform data');
|
|
494
|
+
// ... transformation code
|
|
495
|
+
|
|
496
|
+
tracker.checkpoint('Upload to target');
|
|
497
|
+
// ... upload code
|
|
498
|
+
|
|
499
|
+
tracker.summary();
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
## Key Takeaways
|
|
505
|
+
|
|
506
|
+
- šÆ **Dynamic batch sizes** - Adjust based on file size
|
|
507
|
+
- šÆ **Parallel processing** - Use worker pools for multiple files
|
|
508
|
+
- šÆ **Partitioning** - Time/category-based for efficient queries
|
|
509
|
+
- šÆ **SNAPPY compression** - Best balance for most cases
|
|
510
|
+
- šÆ **Monitor metrics** - Track and optimize performance
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Next Steps
|
|
515
|
+
|
|
516
|
+
Continue to [Module 8: Best Practices](./03-pattern-guides-parquet-08-best-practices.md) to learn production patterns, error handling, and troubleshooting.
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
[ā Previous: Module 6 - S3 Integration](./03-pattern-guides-parquet-06-s3-integration.md) | [Back to Guide](../parquet-readme.md) | [Next: Module 8 - Best Practices ā](./03-pattern-guides-parquet-08-best-practices.md)
|
|
521
|
+
|
|
522
|
+
## Related Documentation
|
|
523
|
+
|
|
524
|
+
- [Module 3: Reading Parquet](./03-pattern-guides-parquet-03-reading-parquet.md) - Streaming and validation
|
|
525
|
+
- [Module 8: Best Practices](./03-pattern-guides-parquet-08-best-practices.md) - Production patterns
|