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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/update_top_level_domains.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: update_top_level_domains

on:
schedule:
# Runs "At 06:00 on the 1st of every month"
- cron: '0 6 1 * *'
workflow_dispatch:

permissions:
contents: read

jobs:
update_top_level_domains:
runs-on: ubuntu-latest
steps:
- name: 📚 Git Checkout
uses: actions/checkout@v6

- name: 🎯 Install Dart
uses: dart-lang/setup-dart@v1

# Leaves the file as it is when the list of domains has not changed, so
# no pull request is opened then.
- name: 🌐 Regenerate Top-Level Domains
run: dart run scripts/generate_top_level_domains.dart

# Opened with the bot's token so the pull request's checks run, which
# they don't for one opened with the workflow's own token.
- name: 📤 Open Pull Request
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.BOT_GITHUB_API_TOKEN }}
branch: chore/update-top-level-domains
delete-branch: true
commit-message: 'chore(repo): update the IANA top-level domains'
title: 'chore(repo): update the IANA top-level domains'
body: |
Regenerates the top-level domains `findLinks` recognizes from the IANA root zone list with `melos run generate:tlds`.
committer: Stream SDK Bot <60655709+Stream-SDK-Bot@users.noreply.github.com>
author: Stream SDK Bot <60655709+Stream-SDK-Bot@users.noreply.github.com>
3 changes: 3 additions & 0 deletions STYLE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,9 @@ Sub-tasks:
- `melos run generate:icons` — regenerates the icon font from SVGs in
`assets_source/icons/`. → [Icons](#icons)
- `melos run gen-l10n` — regenerates localization ARB output.
- `melos run generate:tlds` — regenerates the top-level domains the link finder
recognizes from the IANA root zone list. It downloads the list, so it is not
part of `generate:all`.


## Documentation
Expand Down
5 changes: 5 additions & 0 deletions melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ command:
# List of all the dev_dependencies used in the project.
dev_dependencies:
alchemist: ^0.13.0
benchmark_harness: ^2.4.0
build_runner: ^2.10.5
fake_async: ^1.3.3
json_serializable: ^6.9.5
Expand Down Expand Up @@ -138,6 +139,10 @@ scripts:
run: melos exec -c 1 --file-exists="stream_icons.yaml" -- "dart run \$MELOS_ROOT_PATH/scripts/generate_icons.dart"
description: Generate icon font and Dart classes from SVG files.

generate:tlds:
run: dart run scripts/generate_top_level_domains.dart
description: Regenerate the top-level domains the link finder recognizes from the IANA root zone list.

generate:pigeon:
run: |
melos exec -c 1 --file-exists="pigeons/messages.dart" -- "
Expand Down
7 changes: 7 additions & 0 deletions packages/stream_core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## Upcoming

### ✨ Features

- Added `findLinks` and `findLinkAt`, which find the web links in a text, with
or without a scheme, such as `https://example.com` or `example.com`.

## 0.5.1+1

### 🔄 Changed
Expand Down
57 changes: 57 additions & 0 deletions packages/stream_core/benchmark/link_finder_benchmark.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/// Link Finder Benchmark
///
/// Measures one `findLinks` call over typical messages, long texts in several
/// scripts, and inputs built to make a link scanner slow. Each score is the
/// time of a single call, in microseconds.
///
/// Usage (run from `packages/stream_core`):
/// dart run benchmark/link_finder_benchmark.dart
///
/// For numbers close to a release build, compile it ahead of time first:
/// dart compile exe benchmark/link_finder_benchmark.dart -o benchmark.exe
/// ./benchmark.exe
library;

import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:stream_core/stream_core.dart';

void main() {
for (final (name, text) in _inputs) {
_FindLinksBenchmark(name, text).report();
}
}

final _inputs = <(String, String)>[
('short message', 'Some link: youtube.com'),
(
'typical message',
'Hey! The release notes are at getstream.io/chat/docs and the demo is '
'on youtube.com/watch?v=abc. Ping me at me@x.io if anything breaks 🙂',
),
('prose with links, 3.6k', 'See getstream.io/chat or https://x.io/a?b=c, or mail me@x.io. ' * 60),
('plain words, 5k', 'hello ' * 850),
('many links, 5k', 'a.co ' * 1000),
('Cyrillic, 5k', 'Привет мир. ' * 420),
('Chinese mixed with ASCII, 5k', '中a' * 2500),
('emoji, 2k', '🐼a.b ' * 400),

// Inputs built to make a link scanner slow.
('Chinese, ASCII and dots, 10k', '中a.' * 3400),
('closing parentheses, 20k', ')' * 20000),
('dots, 20k', '.' * 20000),
('one-letter labels, 10k', 'a.' * 5000),
];

// Measures one `findLinks` call over [text].
class _FindLinksBenchmark extends BenchmarkBase {
_FindLinksBenchmark(String name, this.text) : super('findLinks: $name');

final String text;

@override
void run() => findLinks(text);

// One call per measurement, so the score is the time of a single call.
@override
void exercise() => run();
}
1 change: 1 addition & 0 deletions packages/stream_core/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export 'utils/disposable.dart';
export 'utils/event_emitter.dart';
export 'utils/in_flight_cache.dart';
export 'utils/lifecycle_state_provider.dart';
export 'utils/link_finder.dart';
export 'utils/list_extensions.dart';
export 'utils/network_state_provider.dart';
export 'utils/object.dart';
Expand Down
Loading
Loading