VERSION:
    File: PACKAGE-NOTES.txt
    Package archive: s3-cloudfront-indexer-html-package-v83.zip
    Top folder: s3-cloudfront-indexer-html-package-v83
    Package version: v83
    Build name: PACKAGE-NOTES.txt

CHANGE NOTE:
    Viewer-only click-target comfort fix.

What changed:

    Directory and file name links now have a taller, more forgiving clickable
    area.

    The link itself remains the clickable object. The date and size columns are
    not turned into surprise navigation targets.

Why:

    On dense monospace directory rows, it was possible to hover slightly above
    or below the text and get an arrow cursor instead of the hand cursor. That
    made clicks feel unreliable.

Design choice:

    This release expands the clickable area around the file/folder name while
    preserving classic directory-index behavior.

Kept from v82:

    Real newline joins.
    Deterministic canonical row normalization.
    Name sorting by row.sortName.
    Browser-side compareText().

Viewer source marker now reports:
    directory-browser-viewer-version: v83

What to deploy:

    Replace only:
        lambda-edge-directory-browser/index.mjs

    Then:
        Deploy
        Publish a numbered Lambda@Edge version
        Update CloudFront behavior associations
        Wait for CloudFront deployment

What not to change:

    Keep updater v67.
    Keep updater reserved concurrency at 1.

================================================================================

Deployment:
    Replace the s3-directory-index-updater Lambda code with:
        s3-directory-index-updater/index.mjs

Then set:
    Configuration → General configuration → Edit
    Timeout: 30 seconds
    Memory: 512 MB

================================================================================

Deployment:
    Replace the s3-directory-index-updater Lambda code with:
        s3-directory-index-updater/index.mjs

Manual test event:

{
  "Records": [
    {
      "s3": {
        "bucket": {
          "name": "www.8k.art"
        },
        "object": {
          "key": "beta/s3-cloudfront-indexer/index-updater-test.txt"
        }
      }
    }
  ]
}

Expected:
    beta/s3-cloudfront-indexer/.directory-index.json
    beta/.directory-index.json

================================================================================

Deployment:
    Replace the s3-directory-index-updater Lambda code with:
        s3-directory-index-updater/index.mjs

Then test again with:
        beta/index-updater-test.txt

Expected:
        beta/.directory-index.json

================================================================================

SUPER-FAST MODEL:

    Write-time work beats click-time work.

    S3 upload/delete event
        -> s3-directory-index-updater Lambda
        -> updates .directory-index.json in affected folders
        -> viewer Lambda reads one tiny JSON file
        -> folder dates + file dates + sizes render fast

FILES ADDED:

    s3-directory-index-updater/index.mjs
    policies/s3-directory-index-updater-policy-example.json

VIEWER FALLBACK:

    If .directory-index.json does not exist, the directory browser still falls
    back to live ListObjectsV2 so beginners can deploy without the updater first.

PRODUCTION TARGETS:

    8k.art
    8k.press
    define.com

================================================================================

Performance behavior:

    DIRECTORY_HTML_CACHE_SECONDS = 900
    DIRECTORY_HTML_SHARED_CACHE_SECONDS = 3600
    DIRECTORY_HTML_STALE_WHILE_REVALIDATE_SECONDS = 86400
    PREFETCH_FOLDER_PAGES_AFTER_RENDER = true
    MAX_FOLDER_PAGES_TO_PREFETCH = 12

What this improves:

    When a user opens /beta/, the browser can prefetch folder pages like
    /beta/_images/ in the background. When the user clicks, the next page is
    often already warm in browser/CloudFront cache.

Folder timestamps:

    Still use S3 folder marker metadata.
    Still non-blocking after first page render.
    No recursive scan.
    No direct-child scan.
    No folder size calculation.

================================================================================

CloudFront Function header file:

    cloudfront-function-headers/allow-all-cors-and-inline-text.js

Purpose:

    Optional companion function.
    Use it if you want source-code files to display inline instead of downloading.
    It is not required for directory listings themselves.

Removed:

    cloudfront-function-headers/allow-all-cors-and-inline-text.original.js

Reason:

    The backup/original file was confusing and could be deployed by mistake.

================================================================================

Important file updated:

    cloudfront-function-headers/allow-all-cors-and-inline-text.js

Purpose:

    This is the CloudFront Function response-header file. It controls whether
    source-code files display inline in the browser instead of downloading.

================================================================================

Performance behavior:

    1. Main directory page:
       ListObjectsV2 only, returns fast.

    2. Folder timestamp metadata:
       Loaded after the page displays using:
       ?directory-meta=folder-timestamps

    3. Folder timestamps:
       Still use only S3 folder marker metadata.
       No recursive scan.
       No direct-child scan.
       No folder size calculation.

This gives the best user experience:
    instant page display + folder timestamps shortly afterward.

================================================================================

Performance behavior:

    /beta
        redirects immediately to /beta/

    /beta/_images
        checks the S3 folder marker beta/_images/
        redirects if the marker exists

    /beta/README
        checks beta/README/
        does not redirect if that folder marker is missing

Caches:

    DIRECTORY_HTML_CACHE_SECONDS = 120
    LAMBDA_MEMORY_CACHE_SECONDS = 30
    FOLDER_MARKER_MEMORY_CACHE_SECONDS = 300

Folder timestamps remain enabled and use only S3 folder marker metadata.

No recursive scan is performed.
No direct-child scan is performed.
No folder size is calculated.

================================================================================

Speed fix:

    /beta/_images

now redirects immediately to:

    /beta/_images/

without first asking S3 whether the folder exists.

Folder timestamps remain enabled and use only S3 folder marker metadata.

No recursive scan is performed.
No direct-child scan is performed.
No folder size is calculated.
No artificial folder timestamp request limit is exposed.

================================================================================

Folder timestamp behavior:

    SHOW_FOLDER_LAST_MODIFIED = true

Meaning:

    Folder Last modified = LastModified from the S3 marker object, for example:

        beta/_docs/am/
        beta/_daily-builds/2026-05-18/

No recursive scan is performed.
No direct-child scan is performed.
No folder size is calculated.
No artificial "6 at a time" setting is exposed.

================================================================================

Plain-English folder timestamp setting:

    SHOW_FOLDER_LAST_MODIFIED = 6

Meaning:

    Lambda may ask S3 for up to 6 folder marker timestamps at the same time.

Beginner guidance:

    6 is a good default.
    Use 2 or 3 if pages feel slow.
    Use 6 or 8 if pages have many folders and still feel fast.

================================================================================

Folder timestamp behavior:

    SHOW_FOLDER_LAST_MODIFIED = true
    SHOW_FOLDER_LAST_MODIFIED = 6

Meaning:

    Folder Last modified = LastModified from the S3 marker object, for example:

        beta/_daily-builds/
        beta/s3-cloudfront-indexer/

No recursive scan is performed.
No direct-child scan is performed.
No folder size is calculated.

If no marker object exists, the folder timestamp is left blank.

================================================================================

Fast folder timestamp defaults:

    SHOW_FOLDER_LAST_MODIFIED = true
    FOLDER_LAST_MODIFIED_MODE = "marker"
    FOLDER_LAST_MODIFIED_RECURSIVE = false
    MAX_FOLDER_LAST_MODIFIED_KEYS = 1000
    SHOW_FOLDER_LAST_MODIFIED = 6

Why this is better:

    S3 CommonPrefixes do not include LastModified values, but many S3 folders
    have marker objects whose keys end in "/". HeadObject on that marker object
    is much cheaper than recursively listing all descendants.

Fallback options:

    FOLDER_LAST_MODIFIED_MODE = "direct"
        calculate newest direct child file timestamp

    FOLDER_LAST_MODIFIED_MODE = "recursive"
        calculate newest nested descendant timestamp; slower

================================================================================

Fast default:

    SHOW_FOLDER_LAST_MODIFIED = false

Reason:

    S3 folders are prefixes, not real directories. Calculating folder timestamps
    requires extra S3 list calls. On folders with many child folders, that can
    make navigation feel slow.

Optional experiment:

    SHOW_FOLDER_LAST_MODIFIED = true

If enabled:

    FOLDER_LAST_MODIFIED_RECURSIVE = false
        faster, only direct child files count

    FOLDER_LAST_MODIFIED_RECURSIVE = true
        slower, nested descendants count

================================================================================

Fast folder timestamp defaults:

    SHOW_FOLDER_LAST_MODIFIED = true
    FOLDER_LAST_MODIFIED_RECURSIVE = false
    MAX_FOLDER_LAST_MODIFIED_KEYS = 1000
    SHOW_FOLDER_LAST_MODIFIED = 3

Meaning:

    Folder Last modified = newest direct child file timestamp.

To scan all nested descendants instead, set:

    FOLDER_LAST_MODIFIED_RECURSIVE = true

================================================================================

Folder timestamp configuration is controlled in index.mjs / 8k-art-directory-browser.txt by:

    SHOW_FOLDER_LAST_MODIFIED
    FOLDER_LAST_MODIFIED_RECURSIVE
    MAX_FOLDER_LAST_MODIFIED_KEYS
    SHOW_FOLDER_LAST_MODIFIED

Default:

    SHOW_FOLDER_LAST_MODIFIED = true
    FOLDER_LAST_MODIFIED_RECURSIVE = true
    MAX_FOLDER_LAST_MODIFIED_KEYS = 5000
    SHOW_FOLDER_LAST_MODIFIED = 4

Meaning:

    Folder Last modified = newest file timestamp inside that S3 prefix.

================================================================================

Time zone configuration is controlled in index.mjs / 8k-art-directory-browser.txt by:

    DIRECTORY_LISTING_TIME_ZONE
    DIRECTORY_LISTING_LOCALE
    DIRECTORY_LISTING_TIME_ZONE_LABEL

Default:

    America/Los_Angeles

Example display:

    2026-05-18 03:24:12 PM PDT

================================================================================

Canonical configuration is now controlled in index.mjs / 8k-art-directory-browser.txt by:

    ENABLE_CANONICAL_URL_RULES
    CANONICAL_HOST_RULES
    STRIP_LEADING_WWW_FOR_UNKNOWN_HOSTS

ZIP filename and top folder intentionally match:

    s3-cloudfront-indexer-html-package-v83.zip
    s3-cloudfront-indexer-html-package-v83/

================================================================================

PACKAGE VERSION SUMMARY

Package file:
    s3-cloudfront-indexer-html-package-v83

Version:
    v10.2

Release date:
    2026-05-18

Rule used:
    Every text/code/html/json file in this package now carries its own version
    marker. The Build name inside each file matches that file's exact file name.

Files updated:
    8k-art-directory-browser.txt
    DEPLOYMENT-CHECKLIST.html
    LICENSE.txt
    PACKAGE-NOTES.txt
    QUICKSTART-FOR-BEGINNERS.html
    README.html
    TROUBLESHOOTING.html
    cloudfront-function-headers/allow-all-cors-and-inline-text.js
    lambda-edge-directory-browser/index.mjs
    public-landing-page-example.html
    policies/lambda-edge-trust-policy.json
    policies/s3-list-prefix-policy-example.json

================================================================================

S3 CloudFront Indexer HTML Package v10.1

Release date: 2026-05-18
Build name: nested-slash-html-v10.1

This package replaces the former Markdown documentation files with HTML files.

Version marker:
  The Lambda source now has a source-code-only version/date comment at the very
  top of the file. It is not visible in generated directory listings.

Important Lambda@Edge fix:
  Slashless nested folder URLs such as:
      https://8k.art/beta/s3-cloudfront-indexer
  redirect to:
      https://8k.art/beta/s3-cloudfront-indexer/

This keeps public links working without requiring visitors to type the trailing slash.

Previous package notes:
S3 CloudFront Indexer HTML Package v10

This package replaces the former Markdown documentation files with HTML files.

Converted files:
  README.md -> README.html
  QUICKSTART-FOR-BEGINNERS.md -> QUICKSTART-FOR-BEGINNERS.html
  DEPLOYMENT-CHECKLIST.md -> DEPLOYMENT-CHECKLIST.html
  TROUBLESHOOTING.md -> TROUBLESHOOTING.html

Important Lambda@Edge fix:
  Slashless nested folder URLs such as:
      https://8k.art/beta/s3-cloudfront-indexer
  now redirect to:
      https://8k.art/beta/s3-cloudfront-indexer/

This keeps public links working without requiring visitors to type the trailing slash.

